# The console

## 1.1 Connecting a server

**Who** · <kbd>The Service</kbd>

**Where** · Dashboard → Connect a server.

**Before you start** · The product's address, and the addresses its server calls from.

**The steps**
1. Choose the product. A product already connected isn't offered.
2. Give its address, which Atrium asks every minute whether it's up, and its server's addresses, one a line. A call from anywhere else is refused.
3. Choose **What it may call**: only the modules the product needs. Its key can call nothing else.
4. Connect and issue a key, confirming your password. The key is shown once: store it in the server's secrets now.

**What the record shows** · The server is on the picture, grey until its first report. The audit log has the server and its key, never the secret.

**Who is told** · Nobody.

**What can go wrong**
- *"That product already has a server."* It's on the picture already. Open its drawer to issue a new key.
- *The key was lost.* Open the server's drawer and issue a new key. A server holds two live keys at most, so issuing one when it already has two revokes the older.
- *"Choose at least one module."* A key that can call nothing is no use: pick what the product needs (1.21 changes it later).

## 1.2 Reading the dashboard

**Who** · <kbd>The Service</kbd>

**Where** · Dashboard, the console's first page.

**Before you start** · Nothing.

**The steps**
1. Read the colours. LIVE: its address answers. LINK: it's reporting to Atrium. Red means its address isn't answering. Amber means something needs a look, such as a disk 90% full. Grey means it hasn't reported in 10 minutes, or ever.
2. Click a server for its drawer: its resources, its own dashboard's figures, and what it's done with Atrium today. Click Atrium for its own server, hosts and worker pools.

**What the record shows** · Nothing changes. The servers turn slowly, and wait while the pointer is on the picture or a drawer is open.

**Who is told** · Nobody.

**What can go wrong**
- *A server is grey though the product works.* Atrium can't see inside it. Check that the Atrium client library is running on it and that its key is good.
- *A server's figures are empty.* It reports them through the client library, which each product has yet to adopt.

## 1.3 Adding a client

**Who** · <kbd>The Service</kbd>

**Where** · Clients → Add a client.

**Before you start** · Who it is. People registering their own come with accounts (plan CL).

**The steps**
1. Give its name, short name, kind and where it is. Kinds come from Input Fields.
2. Check how its dates and money should read.
3. Create. There's nothing here about products, on purpose.

**What the record shows** · Its record, holding nothing yet. The audit log has it.

**Who is told** · Nobody. A client added here has no people yet.

**What can go wrong**
- *The kind you want isn't there.* Add it in Input Fields, under Kinds of organisation.

## 1.4 Granting a product

**Who** · <kbd>The Service</kbd>

**Where** · A client's record → Grant.

**Before you start** · The client exists and doesn't already hold that product.

**The steps**
1. Choose the product and its offering. There are no dates to fill in: it's recorded today and runs for the term in Settings, a year by default.
2. Add any agreed terms, then grant it.

**What the record shows** · The entitlement, marked "No instance yet" until the product has made its tenant. The audit log has it.

**Who is told** · The client's Owners, by e-mail and notice. The product's server, by a signed webhook, if it hears `entitlement.granted`.

**What can go wrong**
- *A product can't be chosen.* The client holds it already, or it has no offering yet.
- *What happens when the year ends* isn't decided yet: plan TB.

## 1.5 Suspending and resuming a client

**Who** · <kbd>The Service</kbd>

**Where** · A client's record → the ban icon, or Resume.

**Before you start** · A reason, which is kept.

**The steps**
1. Suspend, and say why. Calls naming it are refused and its people can't reach it. Nothing is deleted.
2. Resume, and say why. Everything opens as it was.

**What the record shows** · The banner with when and why. Its status history and the audit log keep both.

**Who is told** · Its Owners, by e-mail. Each product it holds, by webhook, if the product's server hears `tenant.status_changed`.

**What can go wrong**
- *"Give a reason of at least 10 characters."* The reason is kept, so it has to say something.

## 1.6 Reading usage and limits

**Who** · <kbd>The Service</kbd>

**Where** · Usage, and from it Limits.

**Before you start** · A server has made a call.

**The steps**
1. Choose 7, 30 or 90 days. Read the calls per day, then break them down by server, client or module. Each breakdown adds up to the same calls.
2. Open Limits to see, add or change a client's monthly limit.

**What the record shows** · Figures from the usage log, which is append-only. A changed limit is in the audit log.

**Who is told** · Nobody. A notice appears on this page once a limit is 80% used.

**What can go wrong**
- *A client went over its limit and nothing happened.* Limits are stored and shown; Nuntius is first to enforce one.

## 1.7 Finding out what became of a text

**Who** · <kbd>The Service</kbd>

**Where** · Messages.

**Before you start** · The person's number, or their client's name.

**The steps**
1. Search by number or client, or choose Delivered, Undelivered, Not sent or Not sure.
2. Open the row. Numbers are part-hidden in the list and whole on the message.
3. Read the sentence at the top, then what happened in order.

**What the record shows** · One row per text, however many reports arrive. A sign-in code's text is kept with the code blanked, so nobody can read it here.

**Who is told** · Nobody. The server that sent the text hears of each change by its webhook.

**What can go wrong**
- *Not sure yet.* The provider didn't answer in time, so it may have the text. Atrium doesn't retry, since that could send it twice. A report for that number within the hour settles it. If none comes, it stays Not sure.
- *Not sent.* It never left: the provider refused it, the client's limit was reached, or the client has no sender name it may use. The reason is on the message, and nothing was charged.
- *Undelivered.* The provider sent it and the network couldn't deliver it, usually because the phone was off for too long.

## 1.8 Sending a text again

**Who** · <kbd>The Service</kbd>

**Where** · Messages → a text that's undelivered, not sent or not sure → Send it again.

**Before you start** · Ask whether they got it, if you can. A text in doubt may have arrived.

**The steps**
1. Choose Send it again. For a text in doubt the button says "anyway" and warns that they could get it twice.
2. Confirm. It costs another credit.

**What the record shows** · A new message that points at the first and names you. The first stays as it was.

**Who is told** · The number gets the text again. The server that sent the first hears of the new one's changes by its webhook.

**What can go wrong**
- *There's no button.* It was delivered, it's still on its way, or it's a sign-in code. A code can't be sent again: the person asks for a new one when they sign in.
- *It's not sent, because of the limit.* Sending again counts against the client's month as any other text does.

## 1.9 Connecting and switching a provider

**Who** · <kbd>The Service</kbd>

**Where** · Messages → Channels.

**Before you start** · The provider's API key. For Sailup, also its webhook signing secret. Its sender names, approved with the provider, recorded by `notify:sender`.

**The steps**
1. Choose Connect, and enter the key.
2. For Sailup, copy the report address into its webhook settings.
3. Confirm your password. Atrium asks the provider for its balance to check the key, and sends nothing.
4. To switch, choose Send through this on the one standing by, read what it says about sender names, and confirm your password.

**What the record shows** · The audit log has the connection and each switch, never the key. The key can't be read back here: changing it means entering a new one.

**Who is told** · Nobody.

**What can go wrong**
- *"Refused the key."* It's wrong or revoked, or the account is suspended. Nothing was saved.
- *Balance low.* Top up at the provider. When it runs out, texts come back as not sent, and sign-in codes stop too.
- *Reports have stopped.* Texts are still accepted, and Atrium asks for what it missed every 10 minutes. Check the report address at the provider.
- *After switching, a client's text is refused.* An outside client's text never goes under the company's name, so its sender name must be registered with this provider too.


## 1.10 Reading Billing

**Who** · <kbd>The Service</kbd>

**Where** · Billing, in the console's menu.

**Before you start** · Nothing.

**The steps**
1. Read the money at the top: what was paid this month, tax included, with a line for the nine months before; how many paid periods renew in the next 30 days; invoices waiting on the GRA's E-VAT; withholding certificates still open.
2. Read each product's ladder: its offerings from Free up, each with its yearly and monthly price before tax, what it allows and includes, and how many organisations hold it. "Where organisations start" marks its default.
3. Read the chip beside the product: *Complimentary* means nobody pays for it yet, whatever its prices say; *Charging from (a date)* means its billing is switched on for that day; *Charging* means it's on.
4. Below, read the organisations on their own terms, and the prices agreed with one organisation, each with its date.

**What the record shows** · Nothing changes.

**Who is told** · Nobody.

**What can go wrong**
- *A product isn't on the page.* It has no offerings yet. Its first offering comes from a migration or from Add an offering.

## 1.11 Adding or changing an offering

**Who** · <kbd>The Service</kbd>

**Where** · Billing → a product's Add an offering, or click an offering.

**Before you start** · The prices, before tax, and what the product should allow on it.

**The steps**
1. Give it a name and, when it's new, its code as the product reads it (`standard`, `plus`).
2. Give its prices a month and a year. Leave one empty to not sell it that way; 0 is free.
3. Switch on each limit it has and give its amount, empty for no limit; switch on each feature it includes.
4. Say whether it's on sale, and whether it's where organisations start.
5. Save, confirming your password. The preview on the right is how organisations will see it.

**What the record shows** · The offering, audited. A new price applies from each organisation's next renewal.

**Who is told** · Every organisation's product that holds it hears what it allows, by webhook. No person is told.

**What can go wrong**
- *"The offering organisations start on has to stay on sale."* Make another the default first.
- *"Make another offering the default instead."* A product always has one; making another the default moves it.
- *"This product already has an offering with that code."* Codes are one a product.

## 1.12 Adding a limit or feature to a product

**Who** · <kbd>The Service</kbd>

**Where** · Billing → an offering → Add a limit or feature.

**Before you start** · The code the product will read (`members`, `timetables`), agreed with the product's team.

**The steps**
1. Give its name and code.
2. Choose a limit, with what it's counted in, or a feature.
3. Add it, then give each offering its share.

**What the record shows** · The limit or feature, audited. Its offerings' shares are saved with the offering.

**Who is told** · Nobody until an offering is saved with it.

**What can go wrong**
- *"This product already has a limit or feature with that code."* Codes are one a product.

## 1.13 Agreeing a price with one organisation

**Who** · <kbd>The Service</kbd>

**Where** · Billing → Agree a price, or Change beside one.

**Before you start** · The price agreed, the offering, and until when. The offering needs a yearly list price: only those are offered.

**The steps**
1. Choose the organisation and the offering.
2. Give the agreed price a year before tax, and a month if it's sold monthly. The bars show it against the list price.
3. Give the date it holds until, and a note of who agreed it.
4. Save, confirming your password.

**What the record shows** · The agreed price, audited. After its date the organisation pays the list price at its next renewal.

**Who is told** · Nobody. The organisation's Plans page shows its price with the list price struck through.

**What can go wrong**
- *The date has to be after today.* An agreement already over is ended instead: open it and End the agreement.
- *"Nothing has a yearly price yet."* No offering on sale has a yearly price to agree against. Give one a yearly price on Billing first.

## 1.14 Charging one organisation, or keeping one complimentary

**Who** · <kbd>The Service</kbd>

**Where** · Billing → Set billing for one organisation, or Change beside one.

**Before you start** · Its agreement: an organisation charged from today has agreed to it, since the public terms promise notice to the rest.

**The steps**
1. Choose the organisation and the product. What it has now is shown.
2. Choose *As the product*, *Charged from today* or *Complimentary for good*.
3. For charged, give the days it keeps everything while it chooses a plan (the grace days in Settings, 7 to start).
4. Say who it was agreed with, and how.
5. Save, confirming your password. It takes effect at once.

**What the record shows** · The organisation's own billing, audited, with who it was agreed with. As the product removes it.

**Who is told** · Charged from today: its owners and billing people, by e-mail and notice, with the date to choose by. Its product hears by webhook either way.

**What can go wrong**
- *"Agreed with" is required.* Every change to what an organisation pays says why.
- *Charged again.* Saving charged again keeps the first day and the date to choose by.

## 1.15 Switching billing on for a product

**Who** · <kbd>The Service</kbd>

**Where** · Billing → Switch billing on, beside a complimentary product.

**Before you start** · Everything on the list must be ready: a price for every paid offering on sale; the company's VAT registration and TIN (`BILLING_SELLER_VAT`, `BILLING_SELLER_TIN`); E-VAT connected with the GRA; Paystack able to take payments; and the public terms changed.

**The steps**
1. Read the launch: today, the notice, the first day fees may apply, and the founding price.
2. Read what stands in the way. A red step says what's missing.
3. Choose the first day fees may apply (at least 60 days from today, `subscription.notice_days`) and the founding price, the share off for the organisations already on it.
4. Tick that the public terms say it now, and Switch it on. The password is asked again.

**What the record shows** · The launch, its day and founding price, and who switched it on, in the audit log. On the day the product starts charging, and each organisation's product hears.

**Who is told** · Every organisation on the product, today, once: its owners and billing people get the e-mail beside the form. Organisations complimentary for good aren't told; nothing changes for them.

**What can go wrong**
- *It was a mistake.* Before its day, Call it off: nothing was charged, but the organisations were told, so tell them yourself. After the day it can't be called off.
- *An organisation has a paid plan given complimentary.* It keeps it to the end of its term; everyone else gets the grace days (`subscription.grace_days`) after the day to choose a plan, then Free, with nothing deleted.
- *A school on agreed terms.* Its agreed price and its own billing stand until they end.

## 1.16 Giving money back

**Who** · <kbd>The Service</kbd> (`refund.manage`)

**Where** · Billing → Money back. Find the payment under Paid lately (by an organisation's name or the payment's reference) and choose Give money back; a payment set aside on a stale quote waits under Set aside to return.

**Before you start** · Know why the money goes back: the reasons are Input Fields (`refund_reason`). What the public terms promise about refunds decides how much.

**The steps**
1. Read the payment's period: the days used, and the days that would come back.
2. Choose what happens to the plan. *Keep the plan* for goodwill or an overcharge: the plan runs on. *End the period now*: the organisation moves to Free today, with nothing deleted. *Undo the payment*: as if it was never paid; a plan it replaced, or the period it renewed, carries on, and otherwise the organisation moves to Free. A choice greyed out isn't open to this payment now: its period has ended, or a refund ended it already.
3. Read the amount suggested. Ending a period suggests the unused days, or all of it within 14 days of paying (`subscription.refund_days`); undoing suggests everything left; keeping suggests nothing. It can be lowered, never raised, and never more than is left of the payment.
4. Read what goes back, line by line: the price and each tax, in proportion.
5. Choose why, add a note for the record if it helps, and Give back. The password is asked again.

**What the record shows** · The refund under Money back, as a track: asked, with Paystack, sent back. Its drawer shows how much of what was paid, what it did to the plan, why, who asked and when. What the payment has left to give back shows under Paid lately.

**Who is told** · The organisation's owners and billing people, once the money has gone (`billing.refunded`): how much, where it went back to, and what became of the plan. Never before.

**What can go wrong**
- *Paystack didn't answer.* The refund stays *Asked*. Atrium asks again every ten minutes under the same reference, so it's never refunded twice.
- *It needs the payer's details, or it failed.* The row turns red and the Service is told (`billing.refund_stuck`). See 1.17.
- *Two people give money back on one payment at once.* The second sees what the first left: no more than was paid ever goes back.

## 1.17 Recording a refund sent by hand

**Who** · <kbd>The Service</kbd> (`refund.manage`)

**Where** · Billing → Money back → a red row under On the way back → Record the payout.

**Before you start** · Paystack couldn't send it back by itself: it needs the payer's details (often a mobile-money wallet), or it failed and the money is back in the Paystack balance. Send it yourself from the company's wallet or account first.

**The steps**
1. Read where it should go: the way the organisation paid, and how much.
2. Choose how you sent it (Input Fields, `payout_channel`), the day, the number or account it went to, and the transaction ID.
3. Record the payout. The password is asked again.
4. For one that failed, Ask Paystack again instead: it's asked under a new reference.

**What the record shows** · The refund marked sent back, by hand, with how, where, when and the transaction ID. Whatever Paystack says of it later, a payout recorded by hand stands.

**Who is told** · The organisation's owners and billing people (`billing.refunded`), saying it was sent by hand and how.

**What can go wrong**
- *It isn't stuck.* Only a refund that needs the payer's details or failed can be recorded as sent by hand.
- *Paystack still holds a refund that needs details.* Paystack keeps it until it's given the payer's bank account. Once you've sent the money by hand, close it in Paystack's dashboard so it can't go out a second time.

## 1.18 A refund made in Paystack's dashboard

**Who** · <kbd>The Service</kbd> (`refund.manage`)

**Where** · Billing → Money back → Answer first.

**Before you start** · Someone refunded a payment in Paystack's own dashboard, not from the console. Atrium finds it from Paystack's webhook, or the check every ten minutes when the webhook never came, and records it as keeping the plan. The Service is told (`billing.refund_found`).

**The steps**
1. Read who was refunded, how much, and when.
2. Keep the plan, if the plan should run on. Or Choose, and end the period now or undo the payment (while its period still allows it).

**What the record shows** · The refund on its track, marked made in Paystack's dashboard, and the effect chosen.

**Who is told** · The organisation's owners and billing people, once Paystack has sent the money (`billing.refunded`).

**What can go wrong**
- *Its period has ended.* Only keeping the plan is open.
- *It was chosen already.* An effect is chosen once.

## 1.19 Answering a chargeback

**Who** · <kbd>The Service</kbd> (`refund.manage`)

**Where** · Billing → Money back → Answer first: a red clock for each open chargeback. The e-mail "A chargeback to answer by…" links straight to it.

**Before you start** · Paystack gives **16 hours** to answer; after that it accepts the chargeback by itself and refunds from the balance. The plan keeps running while it's open, and the organisation isn't told.

**The steps**
1. Read the clock (the hours left), what the bank says, and the kind (a chargeback, or a fraud claim).
2. Read the evidence Atrium gathered: the payment (the card, when, by whom), the tax invoice that goes to the bank as the receipt, the payments this card made before, and whether the plan it paid for is still running.
3. Read, or rewrite, what goes to the bank.
4. Defend with the evidence: Paystack sends the invoice's PDF (and, for a fraud claim, who paid and what for) and the bank decides, which can take weeks. Or Accept the chargeback: the money goes back now. The password is asked again.

**What the record shows** · The chargeback under Money back, its status (to answer, with the bank, kept, lost), who answered and when, and what went to the bank. Lost, its drawer lists what Atrium did.

**Who is told** · The Service when a chargeback arrives (`billing.dispute_opened`), once. The organisation only if it's lost (`billing.dispute_lost`): the payment returned, the card no longer used, and what became of the plan. Never while it's open, and never if it's won.

**What can go wrong**
- *Lost, whether accepted, decided by the bank, or left to run out.* The money the bank took back is recorded as a refund of its own: the period ends today and the organisation moves to Free, with nothing deleted (when the period was already over, its plan carries on); a credit note follows; the saved card is dropped, so no renewal tries it again.
- *No invoice to send.* A payment set aside on a stale quote has none, so it can only be accepted.
- *Answered in Paystack's dashboard instead.* Atrium follows the outcome from Paystack's webhook or the check every ten minutes.

## 1.20 Reviewing a withholding certificate

**Who** · <kbd>The Service</kbd> (`certificate.review`)

**Where** · Billing → Withholding certificates → a row under To review.

**Before you start** · A school paid net of withholding and sent the GRA's certificate (`billing.certificate_received` told you).

**The steps**
1. Open the certificate, and read it beside what it should show: withheld from the company (its TIN), withheld by the school, the rate and the amount, and the invoice it's for.
2. Accept the certificate when it matches: the withheld part is settled.
3. Or choose why it doesn't (Input Fields, `certificate_reject_reason`) and Reject it. The password is asked again.

**What the record shows** · The withholding's state (to review, owed, waiting, settled), who reviewed it and when, and, rejected, the reason.

**Who is told** · Rejected: the school's owners and billing people (`billing.withholding_owed`), with the reason and the two ways to settle it.

**What can go wrong**
- *Rejected, or none by its day.* The withheld amount is owed. The school pays it at `id` or sends a corrected certificate, which comes back To review. Until it's settled the school can't pay net of withholding again. The plan carries on.
- *Reviewed already.* A certificate is reviewed once; a corrected one is reviewed in turn.

## 1.21 A server's keys: what they may call, revoking one, switching a server off

**Who** · <kbd>The Service</kbd>

**Where** · Dashboard → a server → **Keys and access**. Or, without the console, `php artisan server:revoke` on the server.

**Before you start** · Your password. For an incident, which key: its last four characters show here and in the product's secrets.

**The steps**
1. **What its keys may call**: press a module to give it or take it away. Its live keys take the change at once.
2. **Revoke this key** beside one key: calls with it stop at once; the server's other key keeps working. Issue a new key first if
   the product needs one to move to.
3. **Switch this server off**: every key stops, and its sign-in with every token it gave out. Connecting the product again starts
   afresh, with a new key and a new sign-in client.
4. Without the console: `php artisan server:revoke <server ID> --key=<last four>`, or `--off`.

**What the record shows** · The audit log has each change to a key (its modules, its revoking) and the server switched off, never a
secret. Each key shows when it was made, last used and the day it ends: a year after it was issued.

**Who is told** · Nobody. **Platform readiness** warns a month before a key ends.

**What can go wrong**
- *A key was leaked.* Revoke that key, not the server's other one; if you can't tell which, switch the server off and connect it
  again.
- *The last module can't be taken away.* A key must be able to call something: switch the server off instead.
- *"Product servers' keys: … ends on …"* in readiness. Issue a new key from the drawer, give it to the product, then revoke the old.

## 1.22 Changing a client's SMS credit by hand

**Who** · <kbd>The Service</kbd>

**Where** · Clients → a client → **Texts**.

**Before you start** · Why (from Input Fields, **Why SMS credit is changed by hand**), and your password.

**The steps**
1. Choose **Add** or **Take away**, the number of texts, why, and a note if it helps.
2. **Change the credit**, then confirm your password.

**What the record shows** · A line in the client's credit, with the reason, the note and you. The client's owners and billing people see
it under Texts as changed by support.

**Who is told** · Nobody, unless the change takes the credit below the low mark or to nothing.

**What can go wrong**
- *Taking more than is there.* The credit goes to nothing, never below, and the line records what was actually taken.
- *Moving a product's own wallet in.* Use the reason **Moved from a product's own wallet**, once the product's own balance is closed.

## 1.23 Pricing SMS credit packs

**Who** · <kbd>The Service</kbd>

**Where** · Billing → **SMS credit**.

**Before you start** · The price, which is the Architect's to decide, and your password.

**The steps**
1. **Add a pack**: how many texts, and its price before tax in cedis. It goes on sale at once.
2. Check the price a text beside each pack: it should fall as the packs grow.
3. **Take off sale** to stop selling one; **Put on sale** to sell it again.

**What the record shows** · The audit log has each pack and each change. Each pack says how many times it was bought.

**Who is told** · Nobody.

**What can go wrong**
- *"Something was bought with this pack, so its price stays as it was."* Take it off sale and add a new one at the new price.
- *Nobody can buy credit.* No pack is on sale: add one.


## 1.24 Watching or stopping a bulk send

**Who** · <kbd>The Service</kbd>

**Where** · Messages → **Bulk sends**, then a send. A text that went in one says so on its own page, with a link to the send.

**Before you start** · Nothing. A product starts a bulk send itself (`POST /v1/notify/batch`); the console only watches and stops.

**The steps**
1. Find the send in the list: its template, its client, how many it was for, how far it has filled, and whether it's sending, finished, cancelled or refused.
2. Open it. While it sends, the river fills every few seconds: delivered, with the networks, didn't arrive, and waiting; below it, the pace the provider takes, about how long until the last one goes, what it reserved, and the segments each text takes.
3. To stop it, choose **Cancel what hasn't gone**, then **Stop them**. Texts that haven't gone stop at once and their cost goes back to the client's credit; what has gone can't be called back.
4. To change how fast bulk sends go, open Channels, then the provider, and set **Bulk sends' pace** to what the provider's account takes.

**What the record shows** · Each recipient is a row in Messages, linked to its send. A finished send shows the share delivered, how long it took from first to last, the texts it took, and what was given back for texts that never left. A cancelled one shows what went before the stop, what was cancelled and given back, and who stopped it and when.

**Who is told** · The product that started the send hears `notify.batch_finished` once, with the counts, when the last text has gone or the send is cancelled. No person is told.

**What can go wrong**
- *Refused before a single text.* Its cost wasn't there (the plan's texts and the credit together fell short), or it would have passed the client's monthly limit. Nothing went and nothing was charged; the product was told at once and can send again once there's credit.
- *"No provider is sending: it waits."* Connect a provider, or switch one on, in Channels. A send with no provider at all ends and gives back what's left.
- *Some texts show "Not sure yet".* The provider didn't answer for those, or sending was interrupted while one was being handed over. They are never sent again by themselves, so nobody gets a text twice.
- *It goes slower than the pace.* Each text waits for the provider's answer before the next; a slow provider sets the speed.

## 1.25 Registering a client's sender name

**Who** · <kbd>The Service</kbd>

**Where** · Messages → **Sender names**. You're e-mailed when a client asks for one.

**Before you start** · An account with each SMS provider, and what the provider needs to register a name (often the client's registration
letter, which you ask the client for).

**The steps**
1. Find the client: names waiting on you are first. Send the name to each provider by its own page or e-mail.
2. Choose **Submitted** once it's with the provider.
3. When the provider answers, choose **Registered**, or **Refused…** with its reason as it said it.
4. Below, keep **The company's name** with each provider as the provider approved it: codes, and clients who may fall back, go under it.

**What the record shows** · Each name's state per provider, when it was submitted and registered, and the audit log's every change.

**Who is told** · The client's people who manage its settings, and its products, when a provider registers or refuses the name.

**What can go wrong**
- *A provider connected after the name was asked for.* It shows **To register** for that provider too; record its answer the same way.
- *A registered name stops working.* If a provider refuses a name when sending, Atrium marks it refused there and falls back as the
  client allows. Record **Registered** again once the provider restores it.

## 1.26 Products' e-mail and the chain of mailers

**Who** · <kbd>The Service</kbd>

**Where** · Messages → **Products' e-mail**, then an e-mail.

**Before you start** · Nothing to read the page. Changing the chain or its limits is on the server (`NOTIFY_MAIL_CHAIN`, `NOTIFY_MAIL_LIMITS`), with each mailer's credentials.

**The steps**
1. Read **The chain**: the mailers in the order e-mail tries them, what each took this month against its limit, and which takes the next e-mail.
2. Under **Sent lately**, each e-mail a product sent: its subject, the client, the address it came from, and how many of its recipients it reached.
3. Open one to see it as it was sent, and each recipient's outcome: which mailer took it, or why none did.

**What the record shows** · One row an e-mail with every recipient on it, frozen as sent; kept for `log.product_email_days` (180 days).

**Who is told** · The product that sent it hears `notify.email_finished` once every recipient has an outcome. No person is told.

**What can go wrong**
- *Not sent, "… refused it or couldn't be reached".* Every mailer in the chain failed for that recipient, three tries over about 20 minutes. Check the mailers' credentials on the server and the provider's status.
- *"Not set up in the mail settings: skipped".* A mailer named in the chain has no settings: fix `NOTIFY_MAIL_CHAIN` or add its settings.
- *A product can't send ("no domain of its own").* Set the product's domain; then verify `notify.<domain>` with the provider before it sends.

## 1.27 Who isn't written to

**Who** · <kbd>The Service</kbd>

**Where** · Messages → **Undeliverable**, then an address.

**Before you start** · Nothing to read the list. To lift a block, why (the reasons are Input Fields, `block_lift_reason`).

**The steps**
1. Find an address or number, or filter: **Bounced**, **Spam**, **Unsubscribed**, **By hand**. Each row says why and for whom: every product, or one organisation's announcements.
2. Open one to see what happened to it, newest first: the bounce or complaint as Amazon SES reported it, the soft bounces counted, who blocked or lifted it.
3. To let products write again, choose why under **Lift it**, add a note if it helps, and **Lift it**. Lift an unsubscribe only when the person asked.
4. To stop every product writing to an address or number yourself, use **Stop writing to one** on the list, with why.

**What the record shows** · Every change, kept for good, with who made it.

**Who is told** · Nobody. A product sees a recipient as blocked, bounced or marked as spam when it reads its e-mail or text.

**What can go wrong**
- *An address keeps coming back.* It bounced again after it was lifted: the mailbox really doesn't work; ask the organisation for a new address.
- *A parent says they never get announcements.* Look for them here as unsubscribed; they can undo it from any announcement's link, or you can lift it when they ask.
- *No bounces arrive.* SES's topic isn't on `NOTIFY_SES_TOPICS`, or its subscription wasn't confirmed: see the deployment notes.

## 1.28 Short links

**Who** · <kbd>The Service</kbd>

**Where** · **Links**, then a link.

**Before you start** · Nothing to read them. To turn one off, why (Input Fields, `link_off_reason`).

**The steps**
1. Find a link by its code (the seven characters after `tutel.ink/`) or by where it goes, or filter: **Working**, **Expired**, **Turned off**.
2. Open one to see its taps over the last 30 days, its first and last tap, and when it ends.
3. To stop it at once, choose why under **Turn it off**, then **Turn it off**. Anyone who taps it then sees that it was turned off and who sent it; the product is told.

**What the record shows** · Where each link goes, by its address cut short (never the full address, which may carry a token), who made it and how (by the product, or shortened in a text), its taps, and the audit log's every change. Nothing about who tapped is recorded anywhere.

**Who is told** · The product that made the link, when the Service turns it off.

**What can go wrong**
- *A school says a link "doesn't work".* Find it by its code: expired links say so to the parent, with who sent it; the school's product can send a new one.
- *A link was sent to the wrong people.* Turn it off: it stops for everyone at once, even those who already tapped it.
- *A product can't make a link to an address.* Links go only to the product's own addresses and the school's verified ones, never an outside site.

## 1.29 Vouchers

**Who** · <kbd>The Service</kbd>

**Where** · **Vouchers**, then a campaign, or a code found by its serial.

**Before you start** · Nothing to read them. To void a code or a batch, why (Input Fields, `voucher_void_reason`). To print a batch, a fresh proof: the password again if you signed in more than 15 minutes ago.

**The steps**
1. Each campaign shows as a bar: redeemed, issued but unused, voided, and what's left to issue (once it has ended, what expired unused). Find one by its name or its prefix (`JIS27`).
2. To help someone with a card, type its **serial** (`JIS27-002433`, printed beside the code) or the code itself under **Find a code**. The code's page shows its life: issued, redeemed (with the product's own reference, such as an application), voided, or refused at a portal.
3. To stop a code that hasn't been used, choose why under **Void it**, then **Void it**. It's refused for ever, at once; a redeemed code keeps what it granted.
4. On a campaign, a ready batch can be printed (**Print sheets**, ten cards to an A4 sheet) or downloaded as a **CSV** for a print house, and voided whole (**Void**, with why) if the cards were lost.
5. **Close it early** ends a campaign now: no more codes, and its unused codes stop working.

**What the record shows** · The campaign's figures and its redemptions a day, each batch from generating to ready to printed, and each code's history, never edited. A code itself is never shown: only its last three characters, since it's kept as a keyed hash.

**Who is told** · The product that opened the campaign, when the Service voids a code or a batch or closes it (`vouchers.changed`).

**What can go wrong**
- *A parent says their code is "used".* Find it by its serial: its page says when it was redeemed and the product's reference, never who.
- *A box of cards went missing.* Void its batch: every unused card in it stops working at once; cards already used are untouched.
- *Print sheets is gone.* A batch's codes leave Atrium a week after its first download (30 days if nobody downloads it). The printed cards still work; if they're lost, void the batch and have the product ask for another.
- *A code typed by a parent is "mistyped".* Its last character checks the others: one wrong character, or two swapped, is caught before anything is looked up.
