Skip to content

feat(regulations): add the Regolamenti section, procedure, diff and merge - #150

Draft
lorenzocorallo wants to merge 4 commits into
mainfrom
feat/regulations-section
Draft

lorenzocorallo wants to merge 4 commits into
mainfrom
feat/regulations-section

Conversation

@lorenzocorallo

@lorenzocorallo lorenzocorallo commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Regolamenti, part 1 of 2: the dashboard side of the regulations editor (spec decisions 5–13). Everything except the editor itself, which comes in the stacked follow-up.

What's in it

  • Pages (Italian): Documenti, a document's published versions and its drafts, Bozze, Deleghe, and per draft the procedure page, the differences view and the merge page.
  • Procedure:
    • The states are drawn as a stepper. Transitions come from the draft's can; a blocked one stays visible and says why.
    • "Registra l'approvazione" records the delibera: the body, the date and an optional verbale.
    • Deadlines: 3 days to emanate, and the 10-day window for oppositions shown as information.
    • "Emana e notifica" shows its steps live (PR, checks, merge, tag, release, email, Telegram) with the proof of notification. Rettifica has its own flow.
    • The Segretario manages deleghe; creating or revoking one emails the Direttivo through the backend.
  • Members: viewer, commenter or editor, picked from any IdP account. Merge: a preview, then each conflict side by side with "Mantieni la mia", "Usa l'altra" or "Scrivi a mano". Differences: the category summary, then only the changed articles side by side, with word-level marks, and "Rigenera" until notification.
  • Access:
    • regulations:read|write|manage|rectify each have their own middleware.
    • Someone with only a draft assignment or a delega now gets into the dashboard: loadAccess asks regulations.me.get, and they see Bozze only. The logo leads there.
    • Draft-scoped calls use regulationsAssigneeMiddleware, because the backend owns per-draft access.
  • Contract: regulations.contract.ts is a verbatim copy of feat(regulations): add the regulations.* contract and data model backend#110 (20ca321). Every response is parsed against it. Procedure names were confirmed with the backend thread (merge.execute, not apply).
  • Agent mode:
    • An in-memory fake that follows the backend's rules, with a real local Hocuspocus and xelatex, development builds only. It is not in .output.
    • REGULATIONS_DEV_LEGAL_DIR serves the real RRI and compiles it with legal's class and fonts.
    • AGENT_BACKEND_TOKEN sends a bearer token to a local backend, such as one from the backend's dev IdP shim.
  • Grammar: latex-structure.ts reads legal's docs/grammar.md (nesting capi, hierarchical numbers, \input). It parses legal's example and the migrated RRI (344 nodes) with no problems.
  • Shared UI: FormDialog and Count gain locale="it", and DateField gets placeholder. The bottom nav shortens Telegram when it shows eight services.

Docs: docs/regulations/README.md, plus README, AGENTS.md and docs/design.md.

Verified

  • pnpm check, pnpm typecheck, pnpm test (new tests: navigation and admission, the grammar reader) and pnpm build.
  • In the browser, in agent mode:
    • Documenti and the document page. A version's PDF downloads, compiled by xelatex, with the real class too.
    • Nuova bozza creates a draft and opens it. A new delega appears in the list and shows its toast.
    • An assignee with no permissions (AGENT_PERMISSIONS=none) lands on Bozze. Only Regolamenti is in the rail, and the list shows only their two drafts with their access.
    • A full fake procedure on one draft: a merge with a hand-resolved conflict, sending to approval, the diff going from pending to ready and being regenerated, the delibera, then "Emana e notifica" step by step until the new version exists. Members were added, changed and removed; drafts were renamed and deleted.
    • Mobile layout at 375 px.

Verified end to end against the backend's local stack

Backend #115 (feat/regulations-dev): Postgres, the real compile worker, Hocuspocus, and the dev IdP shim, seeded with the real RRI. One admin dev server per account, each with AGENT_BACKEND_TOKEN minted for it.

  • Admission:
    • dev-editor and dev-delegato have no permissions; the real regulations.me.get admits them and sends them to Bozze.
    • The delegato starts a rettifica from the latest version (me.rectifiable) and gets an editable editor.
  • Lists: the drafts and members are the real ones.
  • Merge: B into A shows the real conflict on "Articolo 2.2.1 (Descrizione generale), comma 2". Resolving it with "Usa l'altra" executes merge.execute, and the result reaches dev-editor's open editor live.
  • Procedure:
    • dev-direttivo sends A to approval; the commenter's open editor turns read-only with an explanation.
    • dev-segretario records the approval with the delibera; the delibera card and the 3-day deadline appear.
  • Deleghe: dev-segretario creates a delega to dev-delegato; it is listed, with its toast.
  • Members: users.search finds "Paolo Presidente", who is then added to draft C.
  • Fixed here: the procedure page no longer asks for emanation.get before an emanation starts.

Once diff.* and emanation.* landed (backend #116, #117):

  • Diff and emanation of A: the differences view shows the real diff (category summary, changed articles side by side, word marks), and the differences PDF downloads (3 pages). The procedure page shows A's completed emanation: PR, CI, merge, tag rri-v2026.11.02, release, email, Telegram skipped; plus the 10-day opposition notice.
  • Draft C, full procedure as dev-segretario:
    • C was sent to approval and its diff came out against the version in force. That surfaced a real hazard: C started from the old import, so its diff undid A's emanated changes. The backend now blocks such drafts with a reason the page shows.
    • Back to bozza, then merged v2026.11.02 through the merge page (source: version, no conflicts); resent, the diff showed only C's own change.
    • Regenerated the diff (3rd generation), recorded the approval, then "Emana e notifica": PR build(deps): bump next from 15.2.3 to 15.2.4 #2, CI, merge, tag rri-v2026.11.03, release, email. It finished after the backend's reload resumed it.
  • Rettifica as dev-delegato: created from v2026.11.03 and fixed a typo in the live editor. "Emana rettifica" made tag rri-v2026.11.03.2, and the document page lists it as "Rettificato da Davide Delegato su delega del Segretario".
  • Blocked emanation: the delegate's old rettifica (stale base) shows a disabled "Emana rettifica" with the backend's reason ("crea una nuova rettifica dalla versione in vigore …").
  • Fixes here:

Not verified

  • The rettifica's "Emana rettifica" in the browser.
  • Signing in for real, which needs a dev OIDC client and the backend's access-snapshot key, both from Lorenzo.

Do not merge without Lorenzo's OK. It depends on the backend's regulations.* router.

…erge

Regolamenti manages the governance documents (v1: the Raccolta dei Regolamenti
Interni) against the backend's regulations.* contract (copied verbatim from
PoliNetworkOrg/backend#110 as regulations.contract.ts):

- Documenti, a document's versions and drafts, Bozze and Deleghe, in Italian.
- Procedure page: states, transitions from the draft's `can`, the delibera,
  deadlines and "Emana e notifica" with its steps live; rettifica.
- Members dialog (viewer, commenter, editor; any IdP account), the differences
  view (categories, then changed articles side by side with word marks) and
  the merge page with side-by-side conflict resolution.
- regulations:read|write|manage|rectify permissions and middleware; a draft
  assignment or a delega alone admits a user to Bozze (regulations.me.get).
- Agent mode: an in-memory fake with a local Hocuspocus and xelatex, the real
  RRI with REGULATIONS_DEV_LEGAL_DIR, and AGENT_BACKEND_TOKEN to call a local
  backend instead.
- A reader of legal's LaTeX grammar for numbering and the fake.

The editor page is a placeholder until the next pull request.
@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

…o check GitHub again

Copies the contract from backend#117 (0249ba0) with can.emanateBlockedBy:
the emanate action shows disabled with the backend's reason (a superseded
base, text that doesn't parse, missing differences). An emanation step that
has been running for 20 s offers "Controlla ora" (emanation.retry, valid
while waiting).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant