Skip to content

Align backend#175

Draft
bdb-dd wants to merge 244 commits into
digdir:mainfrom
bdb-dd:align-backend
Draft

Align backend#175
bdb-dd wants to merge 244 commits into
digdir:mainfrom
bdb-dd:align-backend

Conversation

@bdb-dd
Copy link
Copy Markdown

@bdb-dd bdb-dd commented May 7, 2026

Suggested changes for aligning our Umbrac and infrastructure with the setup of Infoportal.

These changes have not been evaluated by hand (yet).

larsekhansen and others added 30 commits January 23, 2026 11:35
- Restructure project as monorepo with apps/cms and apps/frontend
- Add Strapi v5.33.4 CMS with SQLite database
- Create 6 content types: artikkel, side, eksempel, veiledning, faq, merkelapp
- Create 5 block components: advarsel, faq-innhold, lenke, lenkeliste, tekst
- Configure public API permissions via bootstrap script
- Add seed data for testing (3 articles, 3 FAQs, 2 examples, etc.)
- Connect Astro frontend pages to Strapi API
- Update strapi.ts client and BlocksRenderer for Strapi v5 blocks
- All 18 pages now render content from CMS

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Adds:
- Monorepo structure (apps/cms, apps/frontend)
- Strapi v5 CMS with content types and blocks
- Astro frontend connected to Strapi API
- Designsystemet React components
- Add complete tech stack (Strapi, Astro, Designsystemet, etc.)
- Document project structure
- Add development setup instructions
- Explain static site architecture and content refresh behavior

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add Strapi preview handler for draft content preview
- Create preview API routes (/api/preview, /api/exit-preview)
- Add PreviewBanner component for editors
- Update strapi.ts to support preview mode with status=draft
- Remove hardcoded fallback content from all pages
- Connect remaining pages to Strapi (kontakt, om-oss, veiledning, sandkasse)
- Add veiledning/[slug] dynamic route
- Delete data.ts placeholder file

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Document which pages are controlled by Strapi vs code, and add
preview mode setup instructions.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove npm scripts from frontend package.json (use deno tasks)
- Remove package-lock.json (use deno.lock)
- Update pnpm-workspace to only include CMS
- Update deno.json with all tasks including e2e tests
- Update README with correct tech stack and commands

Strapi requires Node.js, but frontend runs on Deno 2.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Replace @astrojs/node with @astrojs/cloudflare
- Update astro.config.mjs for Cloudflare Workers
- Update README with correct hosting info

Following the same infrastructure as norge.no:
- Frontend: Cloudflare Workers
- CMS: Azure Web App
- Database: Azure PostgreSQL

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Comprehensive design spec for ki.norge.no portal including:
- Design system tokens (colors, typography, spacing)
- Page structure and information architecture
- Component specifications
- Responsive behavior
- Accessibility requirements

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add Stitch color overrides (#136dec primary) to DS tokens
- Add Public Sans font and Material Symbols icons
- Implement dark mode with class-based toggle and localStorage persistence
- Redesign header with sticky backdrop-blur, logo, mobile menu
- Redesign footer with 3-column layout and partners section
- Create new landing sections: SandboxFeature, ExamplesGrid, GuidanceCTA
- Update Hero with split layout and animated illustration
- Update News, Stats, Pillars, Resources, TargetAudiences with improved styling
- Add ArticleCard image support with zoom hover effects
- Update page templates with consistent hero sections
- Add Playwright tests: visual regression, functional, accessibility (WCAG 2.1 AA)
- Hero: Split layout with gradient image on right
- News: Simplified cards with image zoom on hover
- Sandbox: Left-aligned content, dark background with radial gradient
- Examples: 4-column bordered cards with square images
- Guidance CTA: Split layout with large Material Symbol icon
- Footer: 3-column with partner section (Nkom, Datatilsynet, Digdir)
- Header: Simplified nav labels, "Logg inn" button
- Simplified homepage section order
Replace SVG path-based text with proper logo.svg icon and "KI-Norge" text.
Pin Playwright to 1.44.0 with CommonJS config to work with Deno
runtime. Fix WCAG 2.1 AA color contrast violations across all
components (Footer, Header, ArticleCard, News, ExamplesGrid).
Update test selectors to avoid Astro dev toolbar conflicts.
Generate visual regression baselines for all browsers and viewports.
Replace better-sqlite3 (native addon) with pg (pure JS) to eliminate
Node version lock-in from native module compilation. Simplify
database config to postgres-only and update visual test baselines
to reflect seeded content from fresh database.
- Remove hardcoded preview secret fallback from admin.ts and preview.ts
  so missing PREVIEW_SECRET env var fails safely instead of silently
  using a well-known default
- Add PREVIEW_SECRET to both .env.example files
- Untrack .claude/settings.local.json (user-specific permissions/paths)
- Untrack .strapi-updater.json and .strapi/client/ (auto-generated)
- Add all above to .gitignore along with stray root deno.lock
Document step-by-step plans for two exploratory branches evaluating
Umbraco and Decap CMS as potential Strapi replacements, with known
risks and evaluation criteria for the editorial workflow needs.
Redesign article pages to match the Stitch design reference with
breadcrumb navigation, two-column layout with sticky table of
contents sidebar, metadata with date icon, and proper dark mode
support throughout.
Enable i18n plugin with nb/en locales, add locale pluginOptions to all
content type schemas, ensure locales exist at bootstrap, and pass locale
parameter to seed data and frontend API calls.
Implement arbeidsflyt-logg API for submit/approve/reject workflow,
publish-gate middleware that blocks publishing unapproved content,
planlagt-publisering API with cron for scheduled publishing, varsling
API for user notifications, and comprehensive seed data covering all
workflow states.
larsekhansen and others added 26 commits May 3, 2026 22:43
…nal links

Frontend:
- /eksempler → 301 → /caser
- /eksempler/[slug] → 301 → /caser/[slug]
- Header nav: "Eksempler" → "Caser"
- index.astro forside aktuelt-link default → /caser
- SearchDialog dummy data updated to /caser/ki-chatbot-for-innbyggerdialog
- sok.astro typeLabels/typeRoutes: added 'case' + 'ordbokOppslag', kept 'eksempel'
  as legacy alias mapping to /caser/

Robots.txt:
- Disallow /admin-tilgang, /preview-tilgang, /status, /api/, /503

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Umbraco 17.1.0 → 17.3.5 added new columns (umbracoUserGroup.description) but
without UpgradeUnattended=true the container won't run pending migrations and
queries fail with "no such column" errors, breaking the Delivery API.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Skip-to-main-content link in Layout.astro (visible only on focus)
- AllowedUploadedFileExtensions allowlist + DisallowedUploadedFileExtensions
  blocklist on Umbraco for safer media uploads
- CI workflow: build frontend (Deno/Astro) and CMS (.NET 10) on PR;
  smoke test prod on push to main

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Pin MailKit 4.16.0 explicitly to clear GHSA-9j88-vvj5-vhgr
  (transitive via Umbraco.Cms 17.3.5 → 4.15.1)
- Frontend /api/health now reports uptime + build sha/date for
  rolling-deploy verification

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Hero search placeholder darkened from rgba(17,24,39,0.5) to #5e6776
  (3.37 → 5.71 contrast ratio)
- Ki-ordbok alt-term spans darkened from rgba(0,0,0,0.5) to #525965
  (3.94 → 5.53 on white, 3.77 → 4.85 on light blue background)

Verified via axe-core scan on Forside, Artikler, Caser, Veiledning,
Sandkasse, FAQ, Om oss, KI-ordbok, and an article detail page —
no remaining violations.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- CookieNotice component (essential cookies info, dismissable, persisted in localStorage)
- 1200x630 PNG OG image generated from existing SVG (Twitter/X compat)
- Remove unused eventItem (Arrangement) and tilgjengeligIkon content type code
  Both were commented out, this clears the dead methods, fields, and references

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Deploy script tags currently-deployed image as :prev before pushing new one,
  enabling fast rollback via 'az containerapp update --image ...:prev'
- CI runs Trivy filesystem scan on PR and push, fails on HIGH or CRITICAL
  with available fixes (ignore-unfixed avoids noise from unpatchable issues)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- robots.txt now dynamic via /pages/robots.txt.ts; staging/non-prod hosts
  serve "Disallow: /" so they don't appear in search results
- CODEOWNERS auto-requests review on PRs
- CONTRIBUTING.md documents browser support matrix (last 2 of Chrome/FF/Safari/Edge)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…tent)

The migration deleted any sandkasse-node found under Sider, assuming it was
a duplicate of one at root. When an editor moved the real Sandkasse into
Sider via the UI, the next deploy ran the migration and deleted it.

Lesson: never write a deletion migration that targets a content type without
verifying the "original" still exists. Removed the call from
RunStructureMigrations and replaced the method body with a postmortem comment
so the same shape doesn't get re-introduced.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
After RemoveDuplicateSandkasseUnderSider hard-deleted the real Sandkasse
page (an editor had moved it via the UI; migration treated the move as a
duplicate and called ContentService.Delete which skips the recycle bin),
two changes:

1. All remaining ContentService.Delete() calls in ContentSeeder.cs migrations
   converted to MoveToRecycleBin() — covers the Veiledning Oversikt collapse,
   Eksempler container, Om Oss seksjon flatten, and Ikoner cleanup. Editors
   can now recover any of these from the recycle bin in the UI if needed.

2. New scripts/restore-from-snapshot.sh tool with four subcommands:
   - list: enumerate Litestream snapshots
   - find <text>: search every snapshot for a node by name
   - dump <generation>: open a sqlite shell on a restored snapshot
   - export <generation> <node-id>: dump the node + descendants to SQL for
     review and selective restore

The Sandkasse content itself wasn't restored — editor will rebuild it for
the new design instead. The bug class is closed.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
CMS:
- Drop sandkasse-specific element types (sandkasseSteg, sandkasseFaq) and
  the two block list data types that backed them
- Replace sandkasse content type schema: was 13+ fixed fields across 5 tabs
  (hero/hvem/prosess/resultat/faq), now Artikkelhode + a single innhold block
  list pointing at the same Block List - Artikkel Innhold articles use.
  Editor adds artikkel modules (tekst, prosessteg, trekkspill, etc.) for
  every section
- MigrateSandkasse drops legacy properties + groups for any existing
  sandkasse content type and adds the new fields
- SandkasseSingleInstanceHandler refuses to save a second sandkasse node
- Local-dev seeder creates a placeholder Sandkasse under Sider with
  obvious placeholder content (4 prosess-steg, 3 FAQ accordions)
- Fixed seed-skip logic that was bailing early because RunStructureMigrations
  had already created Caser/KI-ordbok at root before the main seed ran

Frontend:
- Sandkasse interface + mapItem case rewritten to match the new schema
- pages/sandkasse/index.astro mirrors the article page layout (hero +
  block renderer); old fixed sections, illustrations, contact form removed
- Drop unused mapSandkasseSteg / mapSandkasseFaq helpers

Security:
- Drop X-Frame-Options: DENY (was blocking the CMS preview iframe).
  CSP frame-ancestors now lists the prod and local CMS origins explicitly,
  which is the modern equivalent and selectively allows preview embedding

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
CMS:
- Add uSync 17.0.4 NuGet package (auto-registers via uSync.BackOffice startup hook)
- Add apps/cms-umbraco/uSync/v17/ tree: ContentTypes, DataTypes, MediaTypes,
  Languages, MemberTypes, RelationTypes (98 files exported from a live instance)
- Remove Composers/ContentTypeComposer.cs - schema now authoritative in uSync
- Disable Composers/ContentSeeder.cs (renamed to .disabled) - seeded content is
  in uSync; programmatic seeding superseded
- Register appsettings-schema.usync.json in appsettings-schema.json

This brings ki-norge-no in sync with the schema authority approach used by
info-altinn-no and unblocks the rest of the modernization port (Cloudflare
adapter, Entra auth, AKS hosting).
- Replace @astrojs/node with @astrojs/cloudflare adapter
- Remove Deno and Docker deployment artifacts (Dockerfile, .dockerignore, deno.json, deno.lock)
- Add Biome configuration and formatting
- Add Vite client fix plugin for Astro 6 dev mode compatibility
- Update .gitignore for Playwright test artifacts
Imported copy of the Umbraco API client developed by the infoportal team.
Package surface:
- createDeliveryApiClient: typed fetch wrapper with API key auth and
  collection/item query helpers
- mapMedia / getMediaUrl: media-picker shape mapping and URL resolution
- richTextToHtml / getPlainText: Delivery API rich-text node tree to HTML
  (and stripped plain-text) renderer
- Types: UmbracoItem, UmbracoBlock, UmbracoMedia, RichTextNode,
  CollectionQuery, ItemQuery, FetchOptions, DeliveryApiClientOptions
Two intentional behavior changes:

- Role mapping is now config-driven. Each app declares MicrosoftEntraId:RoleMappings + DefaultUmbracoGroup in its appsettings.json instead of hard-coding mappings in C#. Existing mappings are preserved verbatim in config.

- AzureBlobFileSystemComposer auto-disables when Umbraco:Storage:AzureBlob:Media:ConnectionString is empty. Required because the composer is now auto-discovered in both CMSes; without the gate, kinorge (no Azure Blob config) would crash at boot. Altinn's deploy sets this via env var, so the gate is satisfied.
- use HMAC-signature instead of cleartext url param
- Dockerfile rewrite, Litestream removal, single-instance guard stripped, ContainerSupport.cs added, appsettings.Production.json rewritten, docker-compose.yml updated)
- Contains a copy of a shareable library for accessing Azure KeyVault
- Mirror the infoportal deploy stack: per-env Azure media SA Terraform, syncroot base + kinorge-test/kinorge-prod overlays, and CI workflows for image publish, syncroot artifact, and SA plan/apply.
The original ki-norge-no workspace only listed packages/*; with the new
apps/frontend and apps/cms-umbraco (and apps/frontend's @portals/umbraco-client
workspace dep), apps/* must be added. Lockfile is regenerated fresh against
the post-port package set rather than reconstructed from per-commit lockfile
diffs that targeted the monorepo's superset of dependencies.

The legacy npm package-lock.json under apps/frontend is removed.
The port-back introduced three new tool families that drop local artifacts
into the working tree:

- .NET build output (bin/, obj/) under dotnet/Portals.Umbraco.Shared/. The
  cms-umbraco app already had a local rule; this hoists it to the root so
  the rule applies to every .NET project, present and future.
- Cloudflare Wrangler local state (.wrangler/) under apps/frontend/, created
  by wrangler dev/build (KV emulation, asset cache).
- Terraform state cache (.terraform/, *.tfstate*, *.tfplan, crash.log) under
  infrastructure/. The provider plugin cache alone is ~230 MB.
  .terraform.lock.hcl is intentionally NOT ignored — it pins provider
  versions and belongs in the repo.
Pins the azurerm provider to ~> 4.68.0 with the platform hashes that
`terraform init` recorded locally. Committing the lock file gives CI and
other contributors deterministic provider downloads on subsequent inits;
without it, each environment can drift to whatever the constraint resolves
to at that moment.

The kinorge-media-sa-prod lockfile will land the first time prod is
init'd against the same provider versions.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2b36674d-72d3-4a58-98b5-e4f29dce60c4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

Comment @coderabbitai help to get the list of available commands and usage tips.

@larsekhansen larsekhansen changed the base branch from feature/umbraco-migration to main May 7, 2026 12:19
larsekhansen added a commit that referenced this pull request May 7, 2026
244 commits som har levd i en branch i månedsvis. Synker mot main, som bare inneholder notater før dette. 
Verifisert lokalt: frontend build, CMS build og Trivy passerer. 4 transitive HIGH CVEs (Astro 5 build deps) ignorert via .trivyignore, re-eval 2026-08-05.
#153 og #175 retargeta til main. #175 (draft, Align backend) skal ikke merges nå.
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.

2 participants