agentleFS
0avi0avi/skills/angular-spring-contract/SKILL.md

angular-spring-contract

Skill1 starsChanged 3 months agoMITView on GitHub

Owns the contract between an Angular frontend and a Spring Boot backend, and nothing inside either. Trigger when an identifier or a money value loses precision in the browser, when a date shifts by a day between server and client, when an OpenAPI document or a generated client is involved, when RFC 9457 ProblemDetail must be consumed by Angular, when JWT storage, HTTP interceptors, silent refresh, route guards or a 401 mid-request are in play, when pagination, optimistic concurrency or file upload crosses the wire, when a trace id must survive from click to SQL, or when a Playwright storageState token expires mid-suite. Install angular-developer, spring-boot-developer, java-developer, typescript-developer, postgresql-developer and ngrx-signal-store-developer alongside it; this skill defers everything inside a single layer to them.

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Every reference carries a ## Version notes section stating what differs across Angular 19 to 21 and Spring Boot 3.5 to 4.x, and a ## …

    line 58
  2. Distinctive:

    Checklist: all 40 seam rules in one scannable list, with the five that cause the most damage first.

    line 119
  3. Distinctive:

    Seam checklist: all 40 rules in one list, the five most damaging first, each linked to its reference.

    line 154

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Angular and Spring Boot: the Contract Between Them

This skill owns the seam between an Angular client and a Spring Boot server, and only the seam. Full-stack defects concentrate there because no single-technology skill can see both sides of a wire format at once.

What this skill does not own

Ask aboutUse instead
Components, signals, forms, routing, DI, SSR, ARIA, Tailwind, Angular testingthe official angular-developer skill
Controllers, ProblemDetail on the server, Spring Security, JPA, Actuatorspring-boot-developer
Records, sealed types, Optional, BigDecimal semanticsjava-developer
tsconfig, strictness, branded types, discriminated unionstypescript-developer
Column types, keys, constraints, indexespostgresql-developer
SignalStore shape, rxMethod, entity collectionsngrx-signal-store-developer
Writing or running e2e tests, browser drivingMicrosoft's playwright-cli skill
  1. Establish both halves before giving guidance. The Angular major, the Spring Boot major, the OpenAPI generator and its configuration, and the database types in play. Advice correct for Angular 21 and Boot 4 is wrong on Angular 17 and Boot 3.5.
  2. This skill owns only what neither side owns alone. The test: a claim belongs here only if it is false, absent, or misleading when either side is read on its own. Never restate a companion; name it and its file, as in "spring-boot-developer's error-handling.md". If a companion is not installed, say which one is missing and what is therefore unverified, then answer the seam question anyway under a stated assumption. Do not fill the gap by reproducing its content.
  3. The OpenAPI document is the source of truth and generated code is never hand-edited. A hand-edit survives until the next generation and then vanishes, usually in someone else's branch. Change the server, regenerate, commit the generated output or generate in CI, but never patch it.
  4. Every identifier and every money value crosses the wire as a string. A JSON number is an IEEE 754 double. It silently corrupts any integer above 9 007 199 254 740 991 and cannot represent 0.1. This is not a style preference; the corrupted values are in type-pipeline.md with the exact outputs.
  5. A date-only value is not an instant, and an instant is not a local time. LocalDate must not become a JavaScript Date. See dates-and-times.md.
  6. The server is the sole authority on authorisation. A route guard is a UX affordance that stops a user seeing a broken page. It protects nothing, and anyone can skip it.
  7. After changing anything on the seam, regenerate the client and typecheck both halves. The contract is only proven by a clean compile on both sides, not by either alone.

Every reference carries a ## Version notes section stating what differs across Angular 19 to 21 and Spring Boot 3.5 to 4.x, and a ## Gotchas list of the specific mistakes agents make in that area. Read the gotchas even when skimming. Where a claim is executable it has been executed: the numbers and timezone results in the references are program output, not recollection.

Determining the versions and configuration

Step 1. Server: pom.xml or build.gradle.kts for the spring-boot-starter-parent or plugin version, and the Java release. Client: package.json for @angular/core.

Step 2. Find the contract. Look for a committed openapi.json or openapi.yaml, a springdoc dependency, or an openapi-generator invocation in package.json scripts or the build. If there is no document, say so plainly: without one, the contract is whatever the two sides currently happen to agree on, and every claim below is an assumption.

Step 3. Find the generator and its config. The generated client's shape, its date handling and its enum handling all follow generator options, and those options are where most seam defects are configured in rather than coded in.

Step 4. Identify the database types behind the endpoint. bigint, numeric, timestamptz and uuid each have a wire decision attached, and the column type is where the chain starts.

Adding an Endpoint, End to End, In Order

#StepWatch for
1Decide the wire types before writing the DTObigint and numeric become strings. type-pipeline.md
2Write the server DTO and endpointspring-boot-developer owns this
3Decide the failure shapeRFC 9457, one type URI per failure mode
4Regenerate the OpenAPI document, then the clientNever hand-edit the output
5Typecheck the client against the regenerated typesA red compile here is the contract working
6Map the response at the boundary, onceParse strings into domain types at the edge, not in templates
7Handle the failure shape, not just the happy pathAn unhandled ProblemDetail reaches the user as "undefined"

Topics

  • The OpenAPI document and the generated client: what springdoc actually emits, what the generator makes of it, and the three places the generated client contradicts the server that produced it. Read openapi-contract.md
  • Type pipeline: Postgres to Java to the wire to TypeScript, for every type where the naive mapping silently loses data: bigint, numeric, uuid, bytea, enums. Read type-pipeline.md
  • Dates and times: timestamptz versus date, Instant versus LocalDate, ISO 8601 on the wire, and why a Date in the browser is the wrong type for a date. Read dates-and-times.md
  • ProblemDetail: the two error shapes a Spring application actually emits, why the RFC 9457 opt-in does not cover unhandled 500s, and what the Angular interceptor must branch on. Read problem-detail.md
  • Pagination: what a Page<T> puts on the wire, why the default envelope publishes Spring Data's internals, and the one property that works on Boot 3.5 and silently does nothing on Boot 4. Read pagination.md
  • Auth end to end: where the token lives and what that costs under SSR, the measured refresh stampede and the trap in its usual fix, 401 mid-request, why a guard protects nothing, and what a storageState token does to an e2e suite. Read auth-flow.md
  • Optimistic concurrency: ETag and If-Match, why the quotes matter, and what a 412 does and does not tell the client. Read concurrency.md
  • File upload: what a rejected upload actually returns, why the limit has to be published, and where the proxy's limit beats yours. Read uploads.md
  • Tracing: the traceparent header, why the trace has to start in the browser, and why the id is invisible to the client unless you return it. Read tracing.md
  • Checklist: all 40 seam rules in one scannable list, with the five that cause the most damage first. Use this for a review pass. Read checklist.md

Symptom index

SymptomRead
An id ends in 00 that should not, or two records collidetype-pipeline.md
A total is out by 0.01, or by 0.000000000000004type-pipeline.md
10.50 displays as 10.5type-pipeline.md
A date is one day earlier for some users and not othersdates-and-times.md
A date is correct in the UK and Nepal but wrong in the USdates-and-times.md
toFixed(2) rounds 1.005 down to 1.00type-pipeline.md
An error renders as "undefined" in the UIproblem-detail.md
problem.type is undefined after a Boot upgradeproblem-detail.md
A 500 is not shaped like the other errorsproblem-detail.md
pageable, paged or unpaged appear in the generated clientpagination.md
A snapshot test of a response body fails after a Boot upgradepagination.md · problem-detail.md
A spring.* property stopped working after upgrading to Boot 4pagination.md
problem.properties.x is undefined but problem.x will not compileopenapi-contract.md
Every field in the generated client is optionalopenapi-contract.md
--type-mappings appears to do nothingopenapi-contract.md
Users are logged out at random, or one refresh succeeds and the rest failauth-flow.md
Every request 401s and nothing tries to refreshauth-flow.md
The first render is logged out and flips after hydrationauth-flow.md
An e2e test passes alone and fails eighth in the suiteauth-flow.md
A page hangs on a 403auth-flow.md
A write silently overwrote someone else's changeconcurrency.md
If-Match always returns 412concurrency.md
A 412 or 413 arrives with nothing to displayconcurrency.md · uploads.md
An upload fails and the interceptor cannot parse the responseuploads.md
A user reports a failure and nothing links it to a log linetracing.md

Checklist

  • Seam checklist: all 40 rules in one list, the five most damaging first, each linked to its reference. Use it for a review pass over an existing pair. Read checklist.md

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.