How to Use the Admin Panel

A walkthrough of every section - what it's for, and the steps to do the common tasks. Click a section below to expand it.

Controls what customers see across the whole storefront - the site name, the top marquee message, the banner image, and your social/contact links.

1
Go to Configuration in the sidebar.
2
Edit the site name, marquee text, or top-up caption, then upload a new banner image if needed.
3
Add/remove social links (Telegram, Facebook, etc.) - these show in the site footer. The Robux bot's Contact Support button uses only the Telegram link from this list (change it here and the bot follows straight away); other platforms, and the website contact page, are not shown in the bot.
4
Toggle Maintenance Mode to close the whole store temporarily (customers see a maintenance message, no new orders can be placed).
5
Click Save at the bottom - changes apply to the live site immediately, no deploy needed.

Telegram Bots

Six bots, each with one job - a token pasted into the wrong one is the classic mistake, so the panel shows which bot each token actually belongs to.

1
Shop bot - customers place orders here; you get order/delivery-failure alerts.
2
Security bot - approves admin logins (2FA-style).
3
Gamepass bot - Bloxfruit orders that need manual fulfilment.
4
Admin bot - lets you deliver a top-up for free (no payment collected) for orders handled outside the store, e.g. a customer messaging on Facebook - and look up any order, all from Telegram. Message it /start for a persistent button menu (same tap-through style as the customer shop bot): Deliver walks game → package → player ID → confirm. Catalog games verify the player ID first, then deliver automatically; Bloxfruit and other custom games only record the order - you still hand the item over yourself. Restricted to chat IDs in TELEGRAM_ADMIN_BOT_OWNER_IDS by default - nobody else gets a response at all, not even an error.
5
The owner set in that secret can add others without touching Cloudflare - message the admin bot /addadmin and forward a message from that person (or send their chat ID). Added admins can deliver top-ups and look up orders, but only a permanent owner can add or remove one with /removeadmin.
6
Price alert bot - sends an alert whenever the supplier changes what a package costs you (see the Product section below). The owners in TELEGRAM_PRICE_ALERT_CHAT_IDS can add or remove people who receive it: message the bot /addadmin and forward a message from that person (or send their chat ID), /admins to see the list, /removeadmin to take someone off. Added people only receive alerts - they can't change the list.
7
Robux bot - sells Robux gift card codes, paid only with ABA KHQR. There is no wallet at all any more: no top-up, no wallet payment, no My Account screen, no balance shown anywhere, and no Add / Deduct Balance tools. Every purchase is an ABA KHQR payment. Old wallet buttons in earlier chat messages just open the menu. Send it /admin for the dashboard: today's and all-time sales, stock warnings, and paid orders that still need delivery. From there: Customers (open a customer to see orders, block / unblock), Orders (open one to see its codes, download its receipt, or Deliver Now once you've added stock), and Search by Telegram ID, @username or order reference. Customers can buy several cards at once with the ➖ / ➕ quantity buttons or by typing a number, and both customers and admins can download a PDF receipt. Tapping Pay with ABA KHQR goes straight to the payment invoice - the bot no longer asks which Roblox username the purchase is for, so new orders, receipts and sale alerts don't show a Roblox player. The menu still has a Check Roblox Player button (or /player) that looks up any username or numeric user ID; each customer can run 8 checks a minute to protect the Elegance quota. You get a Telegram alert (with the exact date and time) for every sale and for low or empty stock. When a customer pays with ABA, the bot saves who paid - payer name, account, bank, transaction ID and approval code - and shows it on the order page and on the receipt. Quick commands: /user, /order, /block, /unblock, /stats. The owner (set in TELEGRAM_ROBUX_OWNER_IDS; until you set it, the IDs in TELEGRAM_ROBUX_ADMIN_IDS count as owners) can add admins without touching Cloudflare - open Admin Team in the dashboard, or send /addadmin, then forward a message from that person or send their Telegram ID / @username. Only the owner can add or remove admins. Customers are never shown how many codes are in stock - the catalog and product page only say whether a card is in stock or sold out (only admins see the counts, and you still get low / empty stock alerts). Its Contact Support and Help screens show one plain button, no emoji: Telegram (the Telegram link set under Contact / Social Links on this Configuration page). If no Telegram link is set, the Contact Support screen says so instead of showing an empty button. Adding stock codes rejects duplicates on its own: a code repeated within what you paste is only added once, and a code that's already stored - on this product or any other, a real gift card code is unique on its own - is skipped rather than added again; you're told how many were added and exactly which text was skipped. In the stock code list (View Available Codes) every code is shown, 25 per page with Prev / Next. Each code has its own permanent number within its product: new codes carry on from the last number, and a number never changes or gets reused when other codes are sold or deleted (so you may see gaps, like 1, 3, 4). A 🔎 Check a Code button on the Stock Codes screen (or /checkcode <text>) looks up one code by its exact text (case doesn't matter) across every product - shows whether it is available or already sold, and if sold, who bought it and a button to its order. Next to it, 🗑 Delete a Code (or /delete <text>, or just /delete and paste the code when asked) finds that code and asks to confirm before removing it - a sold code is refused, and if the same text was stored on more than one product it asks which one instead of guessing. Tap a code's 🗑 number to delete that code, or Delete All Unsold Codes to clear the product - both ask "are you sure?" first, only unsold codes can be deleted (a sold code stays with its order), and the other admins get a notice saying who deleted what. Delete Product (on the product page) removes the product itself.
Rotated a bot token or its webhook secret? Press Re-register all webhooks on this page - until you do, that bot receives nothing, even though the token itself still works. This includes the Robux bot, which now rejects any message that lacks the webhook secret.

Games are pulled from the upstream Elegance catalog automatically. This page lets you customize how each one looks/behaves on your site without touching the supplier's data.

1
Toggle a game Active/Inactive to show or hide it on the top-up page.
2
Rename it, swap its cover image, or put it under Maintenance individually (without closing the whole store).
3
Set the Player ID input label/placeholder text (e.g. "MLBB Account ID") so customers know exactly what to type.
4
Add a fully custom game (like Bloxfruit) that has no upstream supplier at all - its packages come from the Products page instead.

Every diamond/UC/package denomination for every game, with its base cost from the supplier and the retail price you charge.

1
Pick a game from the dropdown to see its full package list.
2
Edit the Price field per package - the row shows your profit live as you type (Price − Base Cost).
3
For a fully custom package (no supplier, e.g. Bloxfruit items), enter your own Cost ($) too - that's what you actually pay to restock it, so profit is calculated correctly.
For a custom/manual game, always set a real Cost - otherwise the Profit report can't tell your margin apart from pure revenue.

Supplier price-change alerts (automatic)

When Elegance changes what a package costs you, an alert is sent automatically to its own dedicated Price alert bot (see Configuration) - kept separate from order alerts so it doesn't get buried in that chat. You don't have to check this page to find out.

1
The alert shows the old cost → new cost, what you currently charge for it, and whether that price still makes a profit.
2
✅ Still profitable = nothing to do. ❌ Not profitable = you are selling at a loss, raise the price here immediately.
3
Packages priced by markup % ("auto") re-price themselves when cost moves, so they normally stay profitable. Packages with a manual price do NOT - those are the ones that can quietly go into a loss.
4
Not sure the alerts reach you? Press Send test price alert in the API Account Details box on the Product page - it sends a sample alert to Telegram straight away. It uses made-up figures, so it never changes a real package.
The row here is also flagged in the table until you save it, so a change you haven't reviewed yet can't disappear from view.

A separate shop for anything that isn't a game top-up - physical or digital items sold with a normal cart/checkout.

1
Create a Category first (e.g. "Skincare", "Merch").
2
Add products under that category: name, price, description, and an image (PNG/JPG/WebP, max 10MB).
3
Optionally link a category to a specific game, so it shows as a section on that game's top-up page instead of the standalone shop.

Discount codes customers type in at checkout - on game top-ups and in the shop cart. The discount is always worked out on the server, so a code can't be faked or reused past its limits.

1
Fill in the form at the top of the page and press Save. Use Generate if you want a random code instead of typing one.
2
Pick Percentage (e.g. 10% off) or Fixed (e.g. $2 off). For percentage codes you can also cap the discount with Max discount.
3
Limits are all optional: Min order, total Usage limit, Per-customer limit, Start/Expiry date, and First order only.
4
Applicable Games: leave on All games, or switch to Specific games and tick as many games as you want the code to work on.
5
Untick Active to switch a code off without deleting it. The list shows how many times each code has been used.
Deleting a code stops it working but keeps its usage history, so past orders still make sense in your reports.

ABA Pay is the only payment method this store uses. This page only lets you switch it on/off for customers - it does NOT let you change the ABA merchant account or API key (those are locked to a developer-only setting for security, so a compromised admin login can never redirect your money to a different account).

1
Toggle Active off if you need to stop customers from paying entirely (e.g. mid-incident).
2
Toggle Maintenance for a temporary pause with a clearer "back soon" message instead of just hiding it.
ABA requires your production domain to be whitelisted on their side before payments work live - that's arranged directly with ABA support, not from this panel.

The full order log - reference, game, account, package, payment method, price and delivery status, newest first.

1
Use Search or the game filter to find a specific order.
2
Click Sync Data to pull the latest delivery status from the upstream supplier.
3
Click the receipt icon on a paid order to view/print its receipt - this is only available once an order shows Completed, since there's nothing to receipt before it's paid.
4
Filter by date range with the date picker above the table.
The package name on an order (and in your Telegram alert and the customer's receipt) is the name you gave it on the Product page, or otherwise the supplier's own name with the game's unit added - e.g. "25 Diamonds". Rename a package there and new orders use your name.

What the statuses mean

1
Pending - an order was started but payment hasn't been confirmed. Most are people who opened the QR and never paid. Nothing to do.
2
Completed - paid and delivered. Finished.
3
Contact Support (delivery failed) - the customer paid but got nothing. Always act on these: top them up by hand or refund them. You're alerted on Telegram when one happens.
4
Expired - the payment window closed unpaid. Any coupon used is given back automatically.
5
Partial Delivery (or Delivery Failed with a reason under it) - Elegance answered, but it delivered only part of the package or refunded it. The customer paid. A partial delivery is not refunded by Elegance: contact them, then top up the rest or refund the customer. The reason is shown under the badge and in your Telegram alert.
6
Processing - paid, and Elegance has not finished the top-up yet (rare). It finishes by itself; you get a Telegram alert if it is still stuck after 2 hours.
Every few minutes (while you or customers use the site) the site compares recent orders with Elegance's own order list. If an order we marked Completed turns out partial or refunded at Elegance, it moves to Delivery Failed and you get a Telegram alert. If a request to Elegance timed out but Elegance did place the order, you get an alert saying so - check the Elegance portal before delivering that order again, so it is never delivered twice.
Unpaid orders older than 30 minutes turn to Expired on their own each time you open this page, so the list doesn't fill up with abandoned checkouts. Nothing newer is ever touched - a payment can still land late.
Every order (website or Telegram) is double-checked with the payment provider directly for up to an hour after it's created - so a customer who pays still gets their top-up even if the "payment received" message from the provider is ever delayed or dropped. For the Robux bot specifically, a payment that still hasn't settled back to us after that hour (this can genuinely happen with ABA bank-transfer payments - the money can leave the customer's account within minutes while ABA itself takes hours to confirm it back to us) is picked up automatically in the background the next time the bot gets any traffic, so it should never need a manual re-check.

Your business dashboard: total revenue, total cost, total profit and margin %, broken down by game and by package, plus a full Sales Log of every paid order.

1
Use the date range filter to see profit for today, this month, or a custom period.
2
The Testing Tools card at the bottom lets you generate fake test orders to preview how charts/reports look, and delete them again afterward.
3
The Delete Sales Log button wipes the entire order/revenue history - it requires typing "DELETE" to confirm on purpose.
Deleting the Sales Log removes real customer order records permanently, including their receipts. There is no undo.

Every customer known from an order, with their visit count, total spent and last activity.

1
Click the clock icon to see a user's activity log (pages visited, when).
2
Click the Ban icon (slash-circle) to block a user's email from placing new orders - existing orders are untouched. Click it again to unban.
3
Click the trash icon to remove their local record - it reappears if a new order comes in under the same email.
Use CSV export (top-right) to pull the full user list into a spreadsheet.

Every game/product image you upload through this panel is stored here. This page is a read-only usage dashboard - how much space is used, and by what.

1
Check this occasionally if uploads start failing - you may be near the storage limit.

The Robux gift card bot speaks English and Khmer (ខ្មែរ). Each customer picks their own language and the bot remembers it.

1
First time: a brand-new customer who sends /start (or any message) is first shown Choose your language / សូមជ្រើសរើសភាសារបស់អ្នក with two flag buttons - 🇬🇧 English and 🇰🇭 ខ្មែរ. After they tap one, the main menu opens in that language.
2
Changing it later: the main menu has a language row at the bottom (🇬🇧 English | 🇰🇭 ខ្មែរ, the current one is ticked ✅), or the customer types /language. It switches at once and applies to every screen, button and message they get - including the automatic confirmation when a payment arrives while they are away.
3
What is translated: everything a customer sees - menu, catalog, quantity picker, Roblox username check, buying (ABA KHQR), delivery messages, My Codes / Cards, help, contact, cancel/status messages, and the notices you trigger from the admin tools (blocked / unblocked, manual code delivery). Dates use Khmer month names. Product names, prices, order numbers, codes and Roblox usernames are never changed.
4
Stays English: the admin screens and the notices sent to admins (new sale, low stock...) - and the PDF receipt, which can only hold plain English letters (the chat messages around it are translated). Admins are never asked to choose a language; they see English until they tap a language button on the menu.
The Khmer wording was written for you to review. A list of every message in English and Khmer is in docs/robux-bot-khmer-review.md - a native speaker can mark any wording to improve, and it is a one-line change per message in functions/_lib/bots/robux/i18n.js.

A security audit log - date/time, success or failure, IP address and device for every admin login attempt.

1
Check this periodically for failed attempts you don't recognize - a burst of failures can mean someone's trying to guess the password.
2
Delete logs clears the whole history if it's grown too long - this is just an audit trail, so it's safe to clear.

Audit site (audit.saitostore.com)

A separate, completely white, locked page that holds the Shion Robux sales sheet: 20 packages (Package Number, Robux List, Price) and a Total Package Sell count for each, with a Total row at the bottom.

a
Change a count: type a number in the Total Package Sell cell and press Enter, or use the small − / + buttons that appear on the row. Or use the Add entry box under the sheet (pick a package, quantity, optional note, Add). Every save is written to the Entries log with time, package, change and note.
c
Profit: Price is your stock price and can be edited per package. Type your Sell Price for each package and the sheet works out Profit Each and Total Profit ((sell price − stock price) × sold), plus a total profit, revenue and stock cost at the top. A package with no sell price yet counts no profit. Each package also has its own Note cell. Every change is logged.
d
Entries log – edit / delete: use Edit on a row to change a sale's quantity or any entry's note (the package count follows), or Delete to remove it (a sale is taken back off the count). Edited rows are marked edited, and a deletion leaves a Deleted line so nothing disappears without a trace.
e
Search & pages: the log shows 20 entries per page (Previous / Next below it). Use the Search box for a note, package number, Robux amount or type (e.g. "sell price"), and From / To for an exact date and time (Cambodia time); Today fills in today. Export entries CSV then downloads only what the search shows.
f
Guide: the black Guide button pinned at the bottom-right of the audit page opens a floating guide over the sheet (also the Guide link at the top; Close or Esc hides it). It explains how the Total row is worked out from your real numbers, how sell price becomes revenue and profit, a bar chart of stock cost against revenue per package, and the steps for using the sheet. You can keep working on the sheet while it is open.
g
Khmer / English: the audit page opens in Khmer by default. The floating ខ្មែរ | EN switch, pinned at the bottom-left of the screen (on the sign-in screen too), changes the whole page (sign-in, sheet, log, guide and messages). Your choice is remembered on that browser. Numbers and the Robux amounts stay as digits; notes you typed yourself are never translated.
b
Export: Export all (top right) downloads one zip with the sheet CSV, the whole entries log CSV and the Excel workbook. Export CSV and Export Excel download the sheet with its Total row; the Excel file also has an Entries log tab and live total formulas. Export entries CSV (above the log) downloads just the log.
1
It signs in in two steps: your username and password, then Approve in the Telegram security bot (there is no authenticator code and no code to type - the approval request arrives in the bot as soon as the password is right). The approval message says AUDIT portal, so you know which site you're approving. The admin panel itself keeps its four steps. The audit site can be open on up to 5 devices at once (each signs itself in with the bot approval; past 5 the oldest is signed out). Because the sign-in is only two steps, saving on this site no longer asks for an authenticator code either; the sign-in cap still applies (a few wrong passwords lock that address for a minute, and no more than 8 approval requests are sent per 10 minutes).
2
Until you sign in it shows only a white sign-in form; every other address on that site is a blank white page.
3
Its sign-in is separate from this panel: signing in there doesn't sign you out here, and a session from one site doesn't work on the other. It can't read or change anything in the store - only this sheet - and an idle tab signs itself out after 15 minutes (use the small Sign out link, top right, to end it sooner).
4
Each sign-in attempt on this Login History record is tagged with the site it was for (admin, audit or timer), so logins to the other sites are easy to tell apart.

Database alert

If the store's database stops answering, the site sends one Telegram message to the owner only (at most once every 10 minutes). While it is down, customers may briefly see “The store is busy right now”. Checkout keeps working from the last known prices and packages for up to 10 minutes, so most customers won't notice. No action is needed - it recovers by itself.


Timer site (timer.saitostore.com)

A separate, locked dashboard for countdown timers you create by hand for any username (real-life countdowns - they are not connected to orders or the bots). Every timer keeps running on the server: refreshing, closing the browser or opening another device never changes the time left.

1
Sign in: two steps - your username and password, then Approve in the Telegram security bot (the message says TIMER portal). There is no authenticator code and no code to type, at sign-in or when you save a change. The timer site has its own session - it doesn't sign you out here, and it can't reach anything else in the store. An idle tab signs itself out after 15 minutes (timers keep running). You can be signed in on up to 5 devices at once - each device signs itself in with the bot approval, and a new sign-in doesn't sign out the others (past 5, the oldest device is signed out). The admin panel still allows only one device at a time.
2
Create Timer: type any username, pick a duration (5 min, 10 min, 30 min, 45 min, 1 hour, 2 hours, 1 day, or set your own hours : minutes : seconds, from 1 second to 365 days) and an optional note. A new timer is Ready - it does not start by itself. Save as draft keeps it as a Draft instead: it never runs and doesn't use up the username, and Mark ready (button or More menu) turns it into a Ready timer (refused if that username already has a live one). The six statuses are Draft, Ready, Running, Paused, Finished and Cancelled; the counters at the top show each one, and notes appear as yellow note chips. One live timer per username (Ready, Running or Paused); a Finished or Cancelled one doesn't block a new one.
3
Buttons: the action buttons sit in front of the username. Ready → Start. Running → Pause and Finish. Paused → Resume and Finish. When the countdown reaches 00:00 the server marks it Finished by itself, stamped with its real end time, and it never goes negative. Many timers can run at once and never affect each other.
4
More (…) menu: View details (times, who created/changed it, live countdown and the full history), Edit, Finish, Cancel timer, History, Delete. Editing a running or paused timer's duration keeps the time already used - 30 → 45 minutes adds 15 minutes to what is left; a duration not longer than the time used is refused (use Finish instead). Finished and Cancelled timers can still have their name and note edited, not their duration.
5
Delete & restore: delete asks for confirmation and is soft - the timer leaves the list but its history stays. A running timer is paused when deleted, so no time is lost or gained. Choose the Deleted status filter and press Restore to bring it back (refused if that username now has another live timer).
6
Countdown precision: the countdown is shown as days, hours, minutes, seconds and milliseconds (e.g. 00d 00h 25m 06s 481ms) and counts down smoothly. The Precision button next to Date range cycles seconds → milliseconds → microseconds and remembers your choice. Milliseconds are the finest the server keeps; microseconds are drawn smoothly from your browser's own clock (they look continuous but are not extra accuracy from the server). The page keeps its clock in step with the server using the quickest network round trip, so the digits are as true as your connection allows (a slow connection can be off by tens of milliseconds).
f
Add or remove time (± Time): every timer that has not ended (Draft, Ready, Running, Paused) has a ± Time button in its row (also … → Add or remove time). Choose Add or Remove, tap quick amounts (+1m +5m +10m +30m +1h +1d, they stack) or type days / hours / minutes / seconds. Before you confirm, Result shows the new time left, the new end time (Cambodia time) and the original duration after the change. The original duration grows or shrinks by the same amount (30 min + 15 min added = 45 min); a running timer's end time shifts by exactly that amount and it keeps running; you can't remove more than what is left (use Finish) or go past 365 days; a finished or cancelled timer can't be changed. It is logged in the history (who, how much, time left before → after) and Undo takes it back.
$
Price & payment: timers are a paid service, so each one can have a Price in USD (optional, e.g. 2.50) and a Paid tick, set in the Create or Edit form. Price and paid can be changed in any state - a finished timer too (… → Edit note, name or price). In the list, the Price column shows the amount and an Unpaid / ✓ Paid pill: tap it to flip it (also … → Mark paid / Mark unpaid). The top of the page shows Total price, Paid and Unpaid for every timer the filters match (all pages, deleted timers excluded unless you pick the Deleted filter). Export CSV (next to the filters) downloads those timers with price, paid / unpaid and paid time, plus the three totals at the bottom. Every price change and paid mark is in the timer's history and in Activity (filter Price / payment), and Undo takes it back. Every timer-site user (owner and team members) can set prices on the timers they can see.
e
Undo / Redo (top of the page) work for the whole system, not just your own changes: create, delete, restore, edit (name, duration, note), Finish and Cancel. Start, Pause and Resume are recorded but not undoable. Undo never erases the past - the original event stays in the history and a new Undo performed / Redo performed line is added, pointing back at it with who pressed it. Undoing a manual Finish returns the timer Paused with the time it had. If the timer has changed since (for example it was started), that step is skipped and the skip is logged, so Undo never overwrites later work. Making a new change clears the Redo list.
7
History & Activity: every action is recorded with who (the admin who approved that login), what, when, and old → new values, including automatic finishes ("System"). Open a timer's details for its own timeline, or press Activity for the latest events across all timers. Times are Cambodia time. Filter Activity with the bar at its top: search a username or timer ID, pick a kind of activity (Created, Started, Paused, Resumed, Finished, Cancelled, Edited, Deleted, Restored, Undo / redo), pick an admin (or System for automatic finishes), and set From / To dates. The filters combine, and Clear resets them.
8
Search & filters: search by username, note or timer ID (e.g. 12 or #12); filter by status (All, Ready, Running, Paused, Finished, Cancelled, Deleted) and by created date range. Everything is done on the server and paged (25, 50 or 100 per page). The page refreshes itself every few seconds, so a change from another admin appears shortly.
a
Khmer / English: the timer site opens in Khmer by default. The floating ខ្មែរ | EN switch, pinned at the bottom-left of the screen (on the sign-in screen too), changes the whole page (sign-in, table, forms, history and messages). Your choice is remembered on that browser. Usernames and notes you typed yourself are never translated.
b
Guide: the black Guide button pinned at the bottom-right of the timer page (also the Guide button at the top; Close or Esc hides it) opens a floating tutorial over the dashboard: how a timer works and which buttons each state has (with how many timers are in each state right now), how changing a duration is worked out, how Undo/Redo behaves, and step-by-step instructions. You can keep working while it is open. The page is plain white, in the same style as the audit site.
c
Team members (sub-admins): you are the owner (username + password, then Approve in the Telegram bot). Press Team at the top to add a team member: a username (3–32 letters, numbers, dot, dash or underscore) and a password typed twice (6+ characters). They sign in at their own address, timer.saitostore.com/team (a page with only the username + password form - no owner login on it), with just those - no authenticator or bot. You sign in at timer.saitostore.com/owner (or /timer/) with your password and a tap in the bot; the two addresses show different forms but open the same dashboard, and neither page mentions the other. The two sign-ins are completely separate: each address uses only its own session, so signing in as a team member at /team never signs you out at /owner (or changes your account there), and the other way round - even in the same browser. A team member sees and manages only their own timers (their own counters, Activity and Undo/Redo), has the same page as you, and cannot create accounts or open Team. Two people may use the same timer username without clashing.
d
What you can do as owner: you see every timer (a small teal tag next to the username shows whose it is) and can start, pause, edit, delete or restore any of them; history records who did it. Use the Whose timers filter to look at one person. In Team you can Rename, Reset password (typed twice; signs them out everywhere), Disable / Enable (a disabled account is signed out at once), Delete (their timers and history are kept), or press View timers / Log. The Sign-in log tab lists every sign-in attempt - time, account, success or failure, IP, device and the reason (wrong password, locked, disabled). Passwords are stored hashed and can never be read back, only reset; 10 wrong tries lock an account for 15 minutes; a team member session lasts 12 hours or until they sign out. Undo / Redo is per person: a team member can only undo their own changes, and yours are yours.
9
Add the domain (one-time): in Cloudflare → Workers & Pages → saito-store → Custom domains, add timer.saitostore.com. No other setup or environment variable is needed - it uses the same database, login and authenticator secret.