- TypeScript 50.8%
- JavaScript 43.5%
- Python 3.5%
- Shell 2.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .github/workflows | ||
| app | ||
| components/ui | ||
| data | ||
| db | ||
| deploy | ||
| docs | ||
| hooks | ||
| lib | ||
| migrations | ||
| public | ||
| scripts | ||
| selfhost | ||
| tests | ||
| vendor | ||
| .gitignore | ||
| .npmrc | ||
| AGENTS.md | ||
| components.json | ||
| eslint.config.mjs | ||
| next.config.ts | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| postcss.config.mjs | ||
| proxy.ts | ||
| README.md | ||
| server.mjs | ||
| tsconfig.json | ||
RosterScope
Working analysis release v0.2, independent of netline2ics. English interface. It reuses the verified local PDF.js / Pyodide converter; PDFs do not upload. Saving explicitly uploads structured events (including crew codes) and printed daily totals to private, authenticated account storage.
Implemented
- UTC 7/14-day duty timeline, operating flights, inferred reporting/release, unknown-code preservation.
- Immutable source snapshots, explicit version time, content deduplication per owner and phase, historical views, change inspection and JSON export.
- Current plan assembled by source version timestamp. New coverage replaces old coverage; a missing date within a new roster remains unknown. Outside a partial import's scope, earlier history remains.
- PDF print cutoff automatically distinguishes realised-by-cutoff, future planned and ongoing entries. Independently confirmed actuals retain separate provenance; legacy imports without the header remain unconfirmed.
- Printed daily FT, DT, FDT, FTcorr and SBDT extraction with date/page attribution, tested on January–November and November PDFs.
- Indicative baseline checks: FDP-01, DUT-02/03/04/05, REST-01, FLT-02 (28-day component only). Monthly EFH candidates use FLT-03/05/06/10; FC candidates use monthly Nov–Mar excess and complete-season April–October excess under Avenant n°6. Partial implementations are labelled; all other catalogue rules remain visible as not implemented.
- Last-arrival delay scenario with fixed reporting, fixed departures and fixed next duty. It increases final operating block time, FDP and duty, reduces following rest, and recalculates downstream cumulative counters. Simulation never alters saved snapshots. It is not a delayed-reporting, extension or discretion engine.
- FT monthly sums and rolling 28 roster days, sector-calculated FTCorr, mapped EFH absence/ground candidates, monthly Nov–Mar FC candidates and seasonal April–October FC candidates. The annual 850h total always adds ground/course EFH and FCT to operating FT; the optional CCT 7.3.2(f) checkbox controls the separate rolling 28-day comparison.
- Account-scoped reads/dedup/deletion/profile, schema validation, cross-origin write rejection, security headers, nonce-based page CSP and restricted converter worker CSP.
Important boundaries
This is a draft analysis workspace, not an operational clearance. The uploaded source catalogue itself requires a validated source profile before PASS. Numerical values within a baseline therefore remain REVIEW. Baseline exceedances are identified as numerical findings, with source references and assumptions, not certified legal conclusions. The complete EASA scheme and approved exceptions are not implemented.
- Only uncomplicated operating-only days get FDP reconstruction. Printed consistent FDT/DT can anchor report/release; otherwise defaults are 60 minutes preflight and 30 minutes postflight. Deviations are visible.
- Timed uncalled home SB has zero operational DT and a separate 25% cumulative credit. Reserve, activated/mixed standby, unknown all-day codes, acclimatisation and source ambiguities block unsupported results. Availability is never assumed rest.
- Cumulative windows currently use consecutive UTC roster dates. Local calendar-day attribution is explicitly unvalidated (catalogue I-09). Elapsed time uses UTC. FDP table lookup uses a user-selected IANA reference zone only with an explicit acclimatisation assumption, and stays REVIEW.
- REST-01 is a home-base planning baseline for supported transitions to an operating FDP. Away-base and irregular actual rest remain unassessable.
- FLT-01 calendar-year and FLT-02 rolling 28-day counters are implemented; FLT-02's 12-consecutive-month component is not.
- FTCorr is recalculated per timed operating sector from duty-plan departure / arrival. BT under 120 minutes uses
BT × (1.12 − BT/1000), floored to a minute; longer BT is unchanged. Credits are attributed to the roster duty date, including flights that arrive after local midnight. Printed FTcorr remains available as source data. FTCorr applies to monthly EFH, not the annual 850h equivalent ledger or actual operating FT. - Experimental fatigue module: independently implemented full published-parameter TPM (S+C+U+W), with selectable Ingre 2014 model-5c comparison, explicit roster-only sleep scenarios or complete-diary analysis, and separate descriptive workload/condition views. Reference-time acclimatisation must be confirmed. Original exposure flags remain descriptive; this is not a fitness assessment. DST transitions and jet-lag adjustment are unsupported.
- Rule catalogue source paths were removed from this repository copy. Original uploaded JSON was not modified.
Persistence and hosting
RosterScope is deployed as a native Next.js application with PostgreSQL and local
password authentication. Sessions are stored hashed in PostgreSQL and checked by
currentUser(); anonymous requests cannot access private account data. Every
query is scoped to the authenticated account. Demo revisions remain in memory
and are never saved automatically.
See the architecture and algorithms reference for the end-to-end data flow, source snapshot model, roster calculations, fatigue engine, persistence boundaries, and implementation limits.
Use the self-hosted deployment instructions. The repository root contains the native application.
node selfhost/prepare.mjs stages the same sources in .selfhost/ for Debian installation. Original PDFs and confidential personal fixtures are intentionally
absent from the repository. Workspace JSON exports can be restored into an empty
account through the authenticated restore wizard.
Checks
Use Node.js 24 and pnpm 11.25.0 from the repository root:
pnpm install --frozen-lockfile
pnpm test
pnpm typecheck
pnpm build
Run pnpm dev for local development. Set DATABASE_URL and the HTTPS
APP_ORIGIN in a private .env.local file for Next.js development. Production
uses pnpm start with the environment supplied by systemd; see the deployment
instructions for proxy and account setup.
Engine regressions can also be run directly:
node --test tests/engine.test.mjs tests/operational-v2.test.mjs tests/fatigue.test.mjs
The PDF runtime regression also runs the actual bundled PDF.js 6.4.299 and Python WebAssembly runtime against private fixture paths. It requires the authoring runtime's canvas shim and uses a temporary CommonJS copy of the unmodified Pyodide assets solely for Node compatibility. Browser behavior does not use that temporary copy.
node tests/pdf-runtime.mjs /path/to/year.1306.idp.pdf /path/to/november.969.idp.pdf
pnpm test:browser runs the dashboard regression checks against a dedicated
verification instance and synthetic account. See deployment verification
for the required database, browser runtime and optional screenshots.
Version 0.2 — operational mappings and source print cutoff
User clarification dated 18 October 2026 is recorded separately in data/operational-mappings.json; the legal catalogue is not silently rewritten to erase a conflicting provision.
- All SB prefixes are home standby; suffixes identify start slots. Standalone timed SB with zero printed DT is assumed uncalled. It has operational DT 0:00, no reporting/release event and no early-reporting exposure flag. It remains availability, not rest.
- A separate cumulative ledger retains 25% standby credit from catalogue SB-05 / EASA CS FTL.1.225(b)(3). Contractual cumulative checks use that ledger, not the zero operational-DT display. Activated or mixed SB needs assignment/contact history and is not inferred.
- FCT = Free Compensation Training, user-confirmed FC equivalent. FCT / FC / FP count 4 EFH per eligible day, once per absence day for the applicable monthly and rolling CCT ledgers. FCT is the only absence-day credit included in the annual 850h ledger; VAC and other absence-day credits are excluded. Separate timed CBT work would remain duty; no CBT duration is invented from an FCT code.
- The initial compensation profile is full-time B737. Stored profiles gain an employment rate default of 1. No general part-time monthly-ceiling scaling is invented.
- Monthly EFH candidate sums calculated operating-sector FTCorr + confirmed GD / course credit + eligible 4-hour absence credits. A 1-hour GD earns 0:30 EFH; LPCB and OPCB have no break and earn 4:30 and 3:30 for their 9-hour and 7-hour sessions; 8-hour SFP1 and CRM sessions include a 1-hour break and earn 3:30; SEC1, S737 and other 4-hour courses have no break and earn 2:00. Unknown codes, untimed ground duty and absence/work conflicts prevent a complete numerical margin.
- From November 2025, winter-month FC candidates use one FC per commenced 4 EFH above the monthly threshold. April–October excess is summed by month and reported at season end, only when all seven EFH months are complete. B737 uses 89 EFH throughout April–October; the temporary Q400 selected-month arrangement for 2026 is not applied.
- Print date/time is read from the first-page
printed by ...header, with UTC inherited from the stated NetLine time convention. Newly imported PDFs default the version timestamp to it and use automatic classification: events completed by print cutoff arerealised_by_print, future entries areplanned, crossing entries arein_progress. All-day entries complete at the next UTC midnight. Explicitly confirmed actuals retain separate provenance. - Latest-roster view combines realised-by-cutoff and future planning. Published snapshots remain accessible; realised-days view includes completed realised days. Within a mixed day, monthly counters split completed and planned flight legs.
- Header-enriched reimport supersedes the identical legacy file in the current merge without deleting its older snapshot. Old imports never stored the print header; users must re-import the original PDF once. No print cutoff is fabricated from an upload date.
- Timeline row margins now show daily FDP / following-rest margins, not an unrelated cumulative balance on an OFF or SB day. Cumulative results remain in the inspector.
Version 0.3 — unavailable-check audit
The full 334-day source roster was audited to reproduce the 20 September screenshot. No personal PDF or extracted crew data is added to the repository.
- Exact user mapping V13 = VAC = 4 EFH was added. VAC13 and V31 are also confirmed VAC equivalents with 4 EFH each.
- Unassigned RES now has zero operating FT, operational DT and cumulative duty credit under RSV-03, even if NetLine omits zero totals. Reserve remains availability, not OFF/rest. Mixed reserve plus work is not treated as an unused zero-credit period.
- Known medical/training/ground-only days have zero operating FT without requiring an explicit FT 00:00 line. NC is sickness without a medical certificate with zero FT/duty; SF is a single off day with zero FT/duty and no absence credit. NC has confirmed zero EFH credit.
- Mixed operating-plus-positioning days can use the printed FDT/DT to anchor report and release when coherent. FDP ends at the final operating arrival; duty continues through the positioning leg. The simple delay simulator remains restricted to uncomplicated operating-only days.
- Realised ordinary home-base rest is now calculated as a retrospective comparison with the normal planning baseline, with REVIEW status and exceptions explicitly unverified. Actual irregularity clauses are not automatically applied or treated as missing numerical data.
- Rest before a supported ground service or home standby can be checked against the normal baseline. Away-base, reserve interaction, unknown boundaries and genuinely missing history have exact context blockers.
- Rolling-window results now include window endpoints, assessable-day count, known subtotal and individual date/code/field/type/reason blockers. A partial day assessment is labelled as partial rather than implying every check is unavailable.
- Data diagnostics groups repeated blockers and distinguishes HISTORY_GAP, CODE_MAPPING_MISSING, ASSUMPTION_REQUIRED, SOURCE_CONFLICT, UNSUPPORTED_CONTEXT and EFH credit review.
- Printed positive FTcorr on a non-flying date is retained for source traceability, but is no longer assigned there as EFH. FTCorr is recalculated from timed flight sectors and attached to their roster duty date, fixing post-midnight arrival attribution.
Expected 20 September values with the full-year source and the explicit base-reference assumption: 7-day duty 6:02; 14-day duty 6:02; 28-day duty 31:18; 28-day operating FT 13:43; next rest 14:13; normal baseline rest margin 1:43. The directly blocking entry was RES on 19 September.
There are no remaining unknown FT/duty mappings in the 334-day source after the confirmed NC/SF mappings. Beginning-of-year windows genuinely need December 2025 history. EFH review remains for unconfirmed code credits and medical credit scope. A numerical result does not establish a complete legal compliance assessment.
Additional checks:
node --test tests/diagnostics-v3.test.mjs
node tests/audit-roster.mjs /path/to/private/full-year-extraction.json
v0.3.3 clarifications
- DH / car positioning add zero EFH; FTCorr is calculated only from timed operating sectors, excluding positioning. Positioning duty accounting is unchanged.
- Flight counters can optionally include CCT 7.3.2(f) credits (confirmed GD / course credit and four hours per eligible absence day) in annual / rolling FT totals. Actual operating FT remains visible, with the equivalent total in parentheses. The rolling chart marks today when it is within the displayed dates.
- Duty timeline checks are grouped into FT, Duty and OFF / REST sections.
- Supported home-base delay simulations show normal 12:30 rest, allowance to 12:20 and crew-approval requirement below 12:20 separately. Approval is never inferred; rest below preceding duty or the ordinary 12-hour floor is blocked. Exceptional approved schemes are outside this implementation. The normal planning baseline remains visible.
- Fatigue research and the original implementation are documented in docs/fatigue-design.md. The later context integration adds a selectable comparison model, but remains experimental and review-gated.
Experimental fatigue module (TPM-SCUW-0.1.0 / TPM-SBCU-5C-0.1.0)
lib/fatigue.mjsindependently implements Ingre et al. 2014 equations 1.1, 1.3–1.9. No FIPS source is bundled; published FIPS numerical examples provide a limited external check of wake components/KSS. This is not validation of individual predictive accuracy or equivalence to a commercial model.- Defaults are editable examples: 22:30 bedtime, 8-hour window, 45-minute commute each way, 45-minute preparation and 60-minute wind-down. Reference zone defaults to Europe/Luxembourg; confirmation is separate from the regulatory profile. Browser/travel timezone never silently shifts the model.
- Roster projection clips habitual windows by work and commute. The envelope varies window length by ±1 hour; this is a sensitivity scenario, not a confidence interval, validated sleep generator or individual prediction interval. No sleep is assumed during timed SB/reserve. Untimed availability and uncovered roster dates are unknown. Before the first roster date only, the seven-day computation lead-in uses explicitly hypothetical habitual sleep.
- Diary mode uses explicit complete-diary coverage, sleep and naps; outside coverage only known work/commuting establishes wakefulness. Unknown state resets the model and breaks the curve. Conflicting sleep/duty/buffer intervals are flagged, not treated as valid sleep. Future diary observations are rejected; future predictions use projection mode.
- Five-minute output grid, event-boundary integration, analytical sleep/wake transitions including the sleep-recovery brake. Sleep inertia is included with published original parameters. Raw KSS extrapolations outside 1–9 are visible. The first 48 hours or fewer than two sleep episodes after initialization remain sensitive and are omitted from summary peaks/events.
- New
fatigue_recordstable stores only the authenticated owner's settings and diary, separate from the pilot profile and imported rosters./api/fatiguehas authenticated GET/PUT/DELETE, owner isolation, cross-origin write checks, payload bounds and validation. Missing account-load results disable saves/deletion to avoid accidental overwrite. Diary JSON export/import and delete are available; example data remains in memory. Browser-local model calculations never call a fatigue vendor. - Workspace JSON exports include fatigue inputs. Dedicated diary export/import is supported; full-workspace restore is available in the self-hosted build.
- Run
node --test tests/fatigue.test.mjsandnode --experimental-strip-types --test tests/fatigue-storage.test.mjsfor model, timezone, diary, schema/migration and owner-isolation checks. - Published numerical agreement and unit checks do not establish scientific or operational suitability. The prototype has no accident-risk output, clearance flag, workload penalty, caffeine model or jet-lag adaptation.
The integrated context layer adds a separately selectable Ingre et al. 2014 model-5c comparison, revision-scoped KSS/SP check-ins, controlled complexity reports, and descriptive elapsed-168-hour workload. See docs/fatigue-context-v02.md. migrations/002.sql must be applied with pnpm migrate before using the new payload-version/concurrency path in an existing PostgreSQL database.
v0.3.4 activity clarifications
- GD (Ground Duty) and S737 (Safety Course 737) count as duty periods. Missing timings remain unknown.
- Timed GF is preflight duty. Before operating flights, its start replaces the default reporting allowance; FDP ends at the last operating arrival. Conflicting printed totals remain visible.
- SEN (Seniority day) and MED1 (Medical Certificate Appointment) contribute zero duty. Neither clarification establishes unrestricted rest. Existing SEN EFH credit is retained; MED1 EFH remains unconfirmed.
- These mappings also apply to previously imported generic events.