All checks were successful
CI / lint-and-test (push) Successful in 19s
- Revised the README to improve clarity in instructions for accessing the calendar miniapp, including changes to the phrasing for consistency. - Updated the configuration documentation to enhance the description of the `EXTERNAL_CALENDAR_ICS_URL` setting, ensuring users understand its purpose and usage. - Improved the import format documentation by translating terms to English for better accessibility to a wider audience. - Enhanced the runbook with clearer instructions regarding access issues when using direct links, emphasizing the importance of using the bot's menu button.
2.7 KiB
2.7 KiB
Duty-schedule import format
The duty-schedule format is used by the /import_duty_schedule command. Only users in ADMIN_USERNAMES or ADMIN_PHONES can import.
Import flow
- Handover time — The bot asks for the shift handover time and optional timezone (e.g.
09:00 Europe/Moscowor06:00 UTC). This is converted to UTC and used as the boundary between duty periods when creating records. - JSON file — Send a file in duty-schedule format (see below). On re-import, duties in the same date range for each user are replaced by the new data.
Format specification
-
meta (required) — Object with:
- start_date (required) — First day of the schedule,
YYYY-MM-DD. - weeks (optional) — Not used to limit length; the number of days is derived from the longest
dutystring (see below).
- start_date (required) — First day of the schedule,
-
schedule (required) — Array of objects. Each object:
- name (required) — Full name of the person (string).
- duty (required) — String of cells separated by
;. Each cell corresponds to one day starting frommeta.start_date(first cell = start_date, second = start_date + 1 day, etc.). Empty or whitespace = no event for that day.
Cell values (single character, case-sensitive where noted)
| Value | Meaning | Notes |
|---|---|---|
| в, В, б, Б | Duty | Any of these four |
| Н | Unavailable | Exactly Н |
| О | Vacation | Exactly О |
| (empty/space/other) | No event | Ignored for import |
The number of days in the schedule is the maximum length of any duty string when split by ;. If duty is empty or missing, it is treated as an empty list of cells.
Example JSON
{
"meta": {
"start_date": "2025-02-01",
"weeks": 4
},
"schedule": [
{
"name": "Ivanov Ivan",
"duty": ";;В;;;Н;;О;;В;;"
},
{
"name": "Petrov Petr",
"duty": ";;;В;;;;;;В;;;"
}
]
}
- start_date is 2025-02-01; the longest
dutyhas 14 cells (after splitting by;), so the schedule spans 14 days (2025-02-01 … 2025-02-14). - First person: duty on day index 2 (В), unavailable on 6 (Н), vacation on 8 (О), duty on 11 (В). Other cells are empty.
- Second person: duty on day indices 3 and 10.
Validation
metaandmeta.start_datemust be present and valid;start_datemust parse asYYYY-MM-DD.schedulemust be an array; each item must be an object with stringname(non-empty after strip) and stringduty(if missing, treated as"").- Invalid JSON or encoding raises an error; the parser reports missing or invalid fields (see
duty_teller.importers.duty_schedule.DutyScheduleParseError).