← Back to the projects

myself-app

This site: a developer profile in English and Spanish, exported as static files and built on entifix.

Overview

This site is a developer profile in English and Spanish, rebuilt as an entifix consumer and exported as static files. Every value it shows is content validated against entities at build, read through the same use cases a backend would run.

It is also where code meant for entifix is incubated before it moves there, and where every significant decision is recorded as an ADR.

Patterns

  • A static export

    Next.js renders every page once, at build, into files served from a private S3 bucket behind CloudFront. There is no server at request time.

  • Content as entities

    Every value on the site is JSON validated against entifix entities before any page renders, so a wrong record stops the build with its path.

  • Layered packages

    Domain, content, an incubator of code meant for entifix, and implementations of UI and adapters. Lint enforces which layer may import which.

  • One use case, two places

    Pages that filter answer in the browser through the same entifix load use case the build runs, over JSON files the build writes.

  • Decisions on record

    Every significant decision is an ADR whose Read when line names the symptom that should send a reader to it — which is how an agent finds the rule before breaking it.

File structure

  • apps/
    • myself-app/The Next.js app: routes, the composition root and browser sources.
    • myself-app-e2e/Playwright journeys against the static export, never a Next server.
    • infra/The Pulumi program: bucket, CloudFront, DNS and the deploy role.
  • packages/
    • domain/Entities, use cases and the rules only this site knows.
    • content/One JSON file per entity, the posts' Markdown and the ADR copies. Imports nothing.
    • entifix-incubator/Code meant for entifix, knowing nothing of this site.
    • implementation/
      • adapters/Where content is read from: the build's files and the browser's.
      • ui/The site's UI, from atoms to templates, with its i18n and styles.
  • tools/
    • conventions/The repository's conventions, asserted: attribution, CI wiring, layers.
  • docs/
    • adr/The decision records, copied into the content by tools/sync-adrs.mjs.

Architecture decisions

Every significant decision is recorded, with the symptom that should send a reader — or an agent — to it before the rule is broken.

The records are written in English.

How the records steer the work

People and agents read the same records. Each one names the symptom that should send a reader to it, so a rule is found before it is broken, not after.

  1. 1DecideA choice that would be costly to undo, or easy to break by accident, gets a numbered record.
  2. 2RecordIts header holds a status, a date, an area and a Read when line: the symptom that should bring a reader back.
  3. 3PointThe repository’s CLAUDE.md sends every agent session to docs/adr, whose README indexes the records.
  4. 4MatchWhen a task meets a symptom — a failing check, a strange build — the agent finds the record whose Read when names it, and follows its rule.
  5. 5EvolveA fact that changes is corrected in place, on a Revised line. A decision that no longer holds gets a new record that supersedes it. Nothing is deleted.

The records below are copied from each repository by a script, and this repository’s CI fails when a copy drifts from its record.

Anatomy of a record: the header of ADR 0020, the newest with a Read when line.
  1. # 20. Project pages, and decision records as contentA number that never changes, and the decision in one line. The README lists them.
  2. - Status: AcceptedWhere it stands. A superseded record stays, and names the record that replaced it.
  3. - Date: 2026-09-30When it was decided. A later correction adds a Revised line below, with its own date.
  4. - Area: dataThe part of the system it governs.
  5. - Read when: a record in `docs/adr` changed and the site still shows the old one, the conventions spec says the ADR copies drift, a project's page is about to show something its repository does not have, a record fails `next build`, or a Spanish reader asks why the records are in EnglishWhat an agent matches against: the symptom it would meet, not the topic.
  1. 0001A Next static export served from S3Accepted

    0001A Next static export served from S3

    Read whenreaching for a server feature — headers(), cookies, a proxy, a route handler — or wondering why this is Next rather than Vite

    The decision

    • Next.js with output: 'export'. next build writes HTML, JavaScript and CSS into apps/myself-app/out, and that directory is the whole deployment.

    Acceptedplatform

    Read the record →
  2. 0002A static adapter behind entifix's repository portAccepted
  3. 0003Pages render at build; interactive parts query in the browserAccepted
  4. 0004An Nx workspace: app, domain, static adapter, contentAccepted
  5. 0005English and Spanish, with localized content fieldsAccepted
  6. 0006Tailwind v4 and everything `@entifix/style` involvesAccepted
  7. 0007Hosting is deferred; the build stays host-neutralAccepted
  8. 0008A landing page of five static sectionsSuperseded in part
  9. 0009The radar's maths is ported, and it runs at build timeAccepted
  10. 0010Content is checked from entity metadata, and every package ships `dist`Accepted
  11. 0011A moving hero, a revealing nav and a blue themeAccepted
  12. 0012The CV as a paper sheet, in variants and two modesAccepted
  13. 0013CloudFront over a private bucket, defined in Pulumi, released on every mergeAccepted
  14. 0014A personal radar: rings for one person, editions in content, filtering over placed blipsAccepted
  15. 0015Customizing the CV in the browser: the URL holds what is hidden, a stylesheet hides itAccepted
  16. 0016entifix queries run in the browser too: one use case, two repositoriesAccepted
  17. 0017A blog of Markdown posts on entitiesAccepted
  18. 0018The incubator owns content mechanics; the app declares sources and rulesAccepted
  19. 0019Layered packages: domain, content, entifix-incubator, implementationAccepted
  20. 0020Project pages, and decision records as contentAccepted