# ATFCD Invitation Manager ## Installation and Secretariat user guide **Version 1.0.0 · Windows / Linux · Browser interface · Local JSON storage** This application creates personalised invitations on your supplied background, maintains the invitation register and produces attendance lists. It is a working Python application with launch scripts, not a compiled Windows executable. Install Python on the server computer; other users only need a browser. ## 1. What is included The original invitation PNG is in `backgrounds/background1.png`. It has been preserved byte-for-byte. The PDF generator places recipient text, a serial number and a vector QR code on top of it; it does not redraw, repaint, correct or otherwise change the background. The four selectable slots are `background1.png`, `background2.png`, `background3.png` and `background4.png`. Only option 1 is initially populated. Upload your own alternative PNGs for options 2–4. Each slot has its own saved layout. The live register starts empty, with no sample guests, no administrator account and no shared default password. The separate `examples/` folder demonstrates outputs using a clearly labelled Sample Recipient. These demonstration files are never imported into the database. ## 2. Windows installation Extract the complete ZIP into a local writable folder, for example `C:\ATFCD_Invitation_Manager`. Do not launch it inside the ZIP. Do not put its live data folder on OneDrive, Dropbox or a network share. Install a 64-bit Python 3.12 or 3.13 runtime. Enable **Add Python to PATH** in the installer. The application requires Python 3.11 or later. Double-click `start_windows.bat` for use on that computer only. For a shared office server, double-click `start_windows_lan.bat`. The first launch creates a private `.venv` folder and installs the required packages. It needs Internet access for this initial installation. Subsequent normal use does not contact any external service. Leave the server window open. The browser should open automatically; otherwise enter: ```text http://127.0.0.1:8765 ``` The server window displays a one-time setup code. Copy it into the browser form, choose an administrator username, enter your name and create a password of at least 10 characters. This code prevents an arbitrary visitor from taking over initial setup. It disappears once setup is complete. To stop the server, press Ctrl+C in its window. Closing a client browser does not stop the shared server. ### Windows firewall for LAN use Other computers must be able to reach the server port. When Windows asks, allow access only on the appropriate **Private** network. Do not permit public-network access unnecessarily. An administrator can create a narrowly scoped rule in an elevated PowerShell window: ```powershell New-NetFirewallRule -DisplayName "ATFCD Invitation Manager - Private LAN" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8765 -Profile Private -RemoteAddress LocalSubnet ``` The launcher does not alter firewall settings automatically. Follow your organisation's network policy. ## 3. Linux installation Extract the ZIP into a local writable directory. Verify that `python3 --version` reports Python 3.11 or later. On supported Debian/Ubuntu/Linux Mint installations, the virtual-environment package may need to be installed separately: ```bash sudo apt install python3-venv ``` Start the application from its folder: ```bash bash start_linux.sh ``` For shared LAN access: ```bash bash start_linux_lan.sh ``` Initial setup and account creation are the same as on Windows. A systemd service example is supplied under `deploy/`; it is an administrator template, not an automatically installed service. Adjust its account and paths before use. ### Manual startup and a different port After first-time installation, the server can be started without the bootstrap launcher: ```bash # Linux .venv/bin/python run.py --host 0.0.0.0 --port 8765 # Windows .venv\Scripts\python.exe run.py --host 0.0.0.0 --port 8765 ``` Replace `8765` with another free port where necessary. Pass the same option to a launcher, for example `bash start_linux_lan.sh --port 8766`. ## 4. Multi-user access Use **one running server for the entire Secretariat**. Every client connects to that server's address, for example: ```text http://192.168.1.50:8765 ``` The example IP is illustrative; use the actual LAN address printed in the server window, or check the host computer's network settings. `127.0.0.1` and `localhost` always refer to the computer on which the browser is running, so they are not the correct address for remote clients. Create separate accounts under **Users & access**. Administrators can manage every function, including users, layouts, background uploads, fonts, audit and backups. Editors can create, edit, personalise, archive and export invitations, but cannot change shared administration settings. Viewers can inspect invitations, reprint PDFs and export registers, without modifying records. Changes are shared through the server-side JSON database. The register refreshes automatically every 30 seconds while it is visible and no form is being edited; **Refresh** updates it immediately. Two users can work simultaneously. If both edit the same invitation, the second stale save is rejected rather than overwriting the first user's changes. Reopen the invitation and reconcile the changes. The server uses local file locks and atomic JSON replacement. It is designed for a single-host Secretariat workspace, not a distributed cluster. Do not run separate application servers against a shared live data folder. ## 5. Create an invitation Open **Invitation register → New invitation**. The honorific/salutation field offers editable suggestions such as His Excellency, Her Excellency, Dr and Mr. This is separate from the official title or position field. Enter the full name, official title, institution, country and invitation date. Full name, country and invitation date are required. The country suggestions are a convenience list; a manually entered value is permitted. Select one of the populated background slots. The serial is assigned only when **Save & generate PDF** succeeds. Before saving, the preview displays a preview serial. Saving stores the record, generates its PDF, and makes **Open saved PDF** available. Open the PDF in the browser to download or print it. You can return to the register and use the PDF button at any time. The serial follows the default form `ATFCD-2026-000001`. Its number is allocated under the database lock. It does not change when you edit, reprint, archive or restore the invitation. The next number is never reset through the browser interface. Internal notes are stored but are not printed and are not included in the QR. The invitation date is always recorded; printing it is optional through the layout editor because it is separate from the event dates already printed in the background. ## 6. Responses and attendance **Answered / Not answered** records whether a response has been received. The two checkboxes are mutually exclusive. **Will attend / Not attending** records the attendance decision. Leave both unticked while the decision is pending. Selecting either decision automatically marks the invitation as answered. Changing the response back to not answered clears the attendance decision. A response may be received without a final attendance commitment; in that case select Answered and leave both attendance boxes unticked. An unanswered invitation is never counted as a non-attendee. The non-attending register includes explicit declines only. These are manually maintained Secretariat statuses. The program does not send emails, monitor email replies, open an RSVP portal or infer responses from QR scans. ## 7. Adjust text and QR placement There are two ways to enter the visual editor: **Adjust layout** within an invitation changes that invitation's draft layout only. Click **Apply to this invitation**, then **Save & generate PDF** to issue the revised document. **Layouts & backgrounds → Edit default layout** changes the template for future invitations using that background. Existing invitations retain the layout and image with which they were issued. Select an element by clicking its guide box or choosing it in the right-hand dropdown. Drag the box to move it; drag its lower-right corner to resize it. Arrow keys move a selected box by one pixel; Shift + arrow moves it by ten. Exact numeric coordinates are also available. For text, adjust X/Y, width, height, font/typeface, font size, minimum size, colour, alignment, wrapping, uppercase and an optional prefix. A bold or italic face is selected through the font list, for example Times-Bold or Times-Italic. The QR has X/Y, square size, colour and polarity settings. Zoom and guide visibility are view controls and are not printed. Coordinates use the source PNG's pixels, measured from its top-left corner. Font sizes use PDF points. The renderer maps one source pixel to 0.75 PDF points and preserves the source image's aspect ratio. The supplied source is 1672 × 941 pixels, a near-16:9 widescreen image; it is not cropped or stretched to force a different ratio. The preview is a server-rendered image of the PDF, not a browser-font approximation. It updates after edits pause briefly. Text automatically shrinks down to the specified minimum size when needed. If it still does not fit, issuing is blocked until the box is enlarged, wrapping enabled, or font sizes adjusted. A warning is shown for missing font characters rather than silently issuing an unreadable name. Review all long titles and institution names. The editor bounds elements within the page, but it does not understand lettering already baked into a background. You remain responsible for avoiding collisions with fixed background text and for leaving the QR unobstructed. Layout JSON can be exported and imported for reuse. Imports must match the current background's pixel dimensions. **Revert changes** restores the layout that was loaded when the editor opened. The serial and QR must remain visible in issued invitations. ## 8. Backgrounds and fonts Upload or replace a slot from **Layouts & backgrounds**. Only PNG files are accepted, up to 20 MB and 20 million pixels. Each image must be at least 640 × 360 pixels, and within the maximum width/height shown in the application. Replacing an image of the same dimensions retains that slot's current layout. A different-sized image receives a scaled starting layout, which must be reviewed in the editor. Slot labels retain the requested filenames even if the uploaded file originally had another name. Previously issued invitations retain an immutable copy of their old background. To switch an existing invitation to a newly uploaded image and latest template, open it, choose **Use latest background & default layout**, review it, and save. PDF standard fonts are available without shipping font files. The application also detects selected installed Windows or Linux fonts where available. For additional fonts, an administrator can upload a supported TrueType `.ttf` file in **Settings & backups**, using a font they are entitled to use and embed. No system font files are distributed with this program. Names in scripts not covered by the selected font need an appropriate font; DOCX display also depends on fonts available to its reader. ## 9. QR code content and scanning The QR is a real generated matrix, rendered as vector shapes in the PDF. It is not a decorative image or a mock code. It contains this pipe-separated text: ```text invitation number|Country|Full name of invited person|Official title ``` The final field is the person's official position, not the honorific. The institution is displayed and stored separately but is not an extra QR field. The fields are encoded as UTF-8. A literal `|` is rejected in these fields to avoid ambiguous parsing. The default is **white modules on dark navy**, fitted inside the supplied dark-blue square. It includes a four-module quiet zone. White-on-dark is inverted polarity: readers must support it, and support varies. The release's white QR was decoded from a rendered PDF after polarity normalisation; this is not a guarantee that every phone camera will accept an inverted code directly. The editor also offers **dark modules on white** for compatibility. Use the mode required by the equipment that will actually scan invitations. Test both an on-screen PDF and a printed proof before distributing invitations. Reducing a widescreen PDF to a smaller paper size reduces the physical QR module size; long names and titles produce denser codes. Enlarge the QR or use a larger print size where necessary. The QR is plain text containing personal data. It is not encrypted or digitally signed, and it is not a public verification URL. Someone who has the card can read or copy it. It does not prove identity or prevent copying and is not an access-control credential by itself. ## 10. Registers and exports The main dropdown provides invited persons, confirmed attending, confirmed non-attending, awaiting response, answered invitations and archived invitations. Search by name, institution, title, country or serial. **PDF**, **Word** and **CSV** export the complete current filtered list, including every matching record across the register's browser pages. Each includes serial, invited person, official title, institution, country, invitation date, response and attendance. PDF and DOCX use A4 landscape tables with repeating headers. CSV is UTF-8 with a BOM for convenient spreadsheet opening; formula-like text is prefixed to prevent spreadsheet execution. Exported lists contain personal data. Handle them according to your organisation's privacy and protocol requirements. They show the status stored at the moment of export, not a live synchronised view. ## 11. Edit, reprint, archive and history Edit a record from the register. Saving creates a new PDF revision without changing its serial. Open **PDF revision history** within the invitation to view previously issued revisions. Each stored PDF has a checksum; a missing or changed file is reported rather than silently regenerated. A simple reprint serves the stored PDF unchanged, even after shared background or layout settings have changed. If data changes are required, use Edit and save a new revision. Archive removes an invitation from active lists without deleting it, reusing its serial or treating it as a decline. Select Archived invitations to restore it. Archiving/restoring changes the record revision but leaves its stored PDF unchanged, so PDF revision numbers may contain gaps after administrative actions. ## 12. Backups and restore The default local storage layout is: ```text data/ database.json invitations, users, settings, layouts, audit database.lock inter-process lock file session.key server session-signing secret backgrounds/ current slot copies and immutable PNG versions issued/<invitation-id>/ retained PDF revisions and JSON snapshots fonts/ fonts supplied by your administrator backups/ last 30 pre-commit JSON snapshots ``` Use **Settings & backups → Download backup ZIP** regularly. This includes the database, background assets, all issued PDFs, revision snapshots and uploaded fonts. It deliberately excludes session secrets and setup codes. A full backup contains password hashes and personal data; keep it protected and keep a separate off-machine copy. The automatic JSON snapshots are a safeguard against a recent write problem. They do not contain the PDF or image assets, do not protect against loss of the server disk, and are not a replacement for a full backup. The operational audit log is not tamper-proof. For restore, stop the server. Preserve the entire current data directory under another name. Extract the backup's `data` directory into the configured data location rather than merging it into a live directory. Start the server and sign in; a new session key is generated when absent. Check counts and open several saved PDFs. Run `manage.py verify` before resuming operations. **Avoid reusing a serial after recovery.** Restoring an old backup cannot know about invitations issued after that backup. Reconcile the recovered register against issued PDFs and the highest number already used. Advance the next sequence through the local administrator utility where necessary; never restart numbering from an earlier value. ```bash # Linux examples; on Windows use .venv\Scripts\python.exe instead .venv/bin/python manage.py verify .venv/bin/python manage.py advance-sequence 250 ``` The latter sets the next number to 250 only if it is higher than the current next number. It does not change any existing invitation. A custom local data directory can be selected with `--data-dir` or `ATFCD_DATA_DIR`. Keep that setting consistent on every restart. ## 13. Password recovery and security Administrators can change roles, disable accounts and reset another user's password through Users & access. A user can change their own password under My account. Password and permission changes invalidate existing sessions; the last active administrator cannot be disabled through the interface. If the administrator password is lost, a person with authorised local access can stop the server and run: ```bash # Linux .venv/bin/python manage.py list-users .venv/bin/python manage.py reset-password administrator # Windows .venv\Scripts\python.exe manage.py reset-password administrator ``` Replace `administrator` with the actual username. The utility prompts for the new password without echoing it and does not automatically change the account's role or activation state. The application includes password hashing, role checks, signed HttpOnly cookies, CSRF tokens, bounded sign-in throttling, stale-edit detection and file-locking controls. These are practical safeguards, not a security certification or a legal-compliance guarantee. JSON records and exported files are not encrypted at rest by the application; use appropriate server access controls, disk protection and backup protection. The LAN launcher uses HTTP. Do not expose that port to the public Internet. For remote or untrusted-network access, arrange HTTPS and network restrictions. Direct TLS can be configured with a certificate and key: ```bash .venv/bin/python run.py --host 0.0.0.0 --ssl-certfile cert.pem --ssl-keyfile key.pem ``` Providing both TLS options enables secure session cookies. When using a separately configured HTTPS reverse proxy, set `ATFCD_HTTPS_ONLY=1` and restrict direct access to the backend. Proxy, certificate, firewall and operating-system administration remain deployment responsibilities. ## 14. Troubleshooting **Python was not found:** install a supported Python version and enable PATH integration. A Windows app-store alias is not a substitute for a working installed runtime. **First installation cannot download packages:** check Internet access and any corporate package/proxy restrictions. The application data is not deleted on installation failure. Re-run the launcher after the problem is resolved. **Port already in use:** stop the other server or choose a different `--port` value. Do not accidentally start a second copy of the same Secretariat workspace. **Other computers cannot connect:** check that the LAN launcher was used, the host stays awake, the client uses the actual server IP, both are on the appropriate network, and the firewall permits the selected port. **The PDF does not reflect a newly changed template:** this is intentional for reprints. Open the invitation, apply the latest background/default, and save a new revision. **Text does not fit:** increase its box, enable wrapping, or reduce the font/minimum size. Ensure it does not then collide with other elements or fixed background text. **Unsupported characters:** select or upload a font containing the required glyphs. For PDF registers, change the report font in Settings. The original Unicode text remains stored; the application blocks an unreadable issued PDF rather than substituting it silently. **White QR is not read by a particular phone:** use a reader that supports inverted polarity or choose standard dark-on-white. Verify a paper proof at the final print size. **Security token expired / sign-in requested:** refresh and sign in again. Preserve any unsaved text before refreshing. Sessions expire after eight hours and are invalidated after password/permission changes. **Database cannot be read:** stop the server, preserve the files, inspect the server log, and restore a verified backup. Do not delete `database.json` to make the error disappear. ## 15. Release testing and limits See `TEST_REPORT.md` for the exact automated checks, rendering review and QR verification performed. The backend was exercised on Linux and the frontend in Chromium with a local API relay. Windows launchers and cross-platform paths are included, but a physical Windows installation and physical-printer/scanner test were not available in the build environment. Perform a short acceptance test on the intended host and actual scanner before issuing live invitations. No email sending, bulk email distribution, public RSVP service, mobile camera check-in, public verification endpoint, digital signature, anti-counterfeit guarantee, hosted service or unlimited-concurrency claim is included.