@abgov/nx-adsp 12.21.0 → 12.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/generators/angular-app/angular-app.js +2 -1
- package/src/generators/angular-app/angular-app.js.map +1 -1
- package/src/generators/angular-app/files/AGENTS.md__tmpl__ +60 -12
- package/src/generators/angular-app/files/CLAUDE.md__tmpl__ +1 -0
- package/src/generators/angular-app/schema.d.ts +2 -0
- package/src/generators/express-service/express-service.js +2 -1
- package/src/generators/express-service/express-service.js.map +1 -1
- package/src/generators/express-service/files/AGENTS.md__tmpl__ +57 -20
- package/src/generators/express-service/files/CLAUDE.md__tmpl__ +1 -0
- package/src/generators/express-service/schema.d.ts +2 -0
- package/src/generators/pean/pean.js +2 -2
- package/src/generators/pean/pean.js.map +1 -1
- package/src/generators/pern/pern.js +2 -2
- package/src/generators/pern/pern.js.map +1 -1
- package/src/generators/pevn/pevn.js +2 -2
- package/src/generators/pevn/pevn.js.map +1 -1
- package/src/generators/react-app/files/AGENTS.md__tmpl__ +63 -6
- package/src/generators/react-app/files/CLAUDE.md__tmpl__ +1 -0
- package/src/generators/react-app/react-app.js +2 -1
- package/src/generators/react-app/react-app.js.map +1 -1
- package/src/generators/react-app/schema.d.ts +2 -0
- package/src/generators/vue-app/files/AGENTS.md__tmpl__ +56 -3
- package/src/generators/vue-app/files/CLAUDE.md__tmpl__ +1 -0
- package/src/generators/vue-app/schema.d.ts +2 -0
- package/src/generators/vue-app/vue-app.js +2 -1
- package/src/generators/vue-app/vue-app.js.map +1 -1
package/package.json
CHANGED
|
@@ -28,7 +28,8 @@ function normalizeOptions(host, options) {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
function addFiles(host, options) {
|
|
31
|
-
|
|
31
|
+
var _a;
|
|
32
|
+
const templateOptions = Object.assign(Object.assign(Object.assign(Object.assign({}, options), options.adsp), (0, devkit_1.names)(options.name)), { offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.projectRoot), pairedProject: (_a = options.pairedProject) !== null && _a !== void 0 ? _a : null, tmpl: '' });
|
|
32
33
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files'), options.projectRoot, templateOptions);
|
|
33
34
|
const addProxyConf = options.nginxProxies.length > 0;
|
|
34
35
|
if (addProxyConf) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-app.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/angular-app/angular-app.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"angular-app.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/angular-app/angular-app.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Angular 19 frontend for the Alberta Digital Service Platform (ADSP).
|
|
4
4
|
Generated by `nx g @abgov/nx-adsp:angular-app`.
|
|
5
|
+
<% if (pairedProject) { %>
|
|
6
|
+
## Paired service
|
|
5
7
|
|
|
8
|
+
This app is paired with **`<%= pairedProject %>`** — the Express backend it talks to.
|
|
9
|
+
API calls use the `/api/` prefix which the Angular dev proxy rewrites to `/<%= pairedProject %>/` on port 3333.
|
|
10
|
+
When working on a feature that spans both projects, read `apps/<%= pairedProject %>/AGENTS.md` for the service context.
|
|
11
|
+
<% } %>
|
|
6
12
|
## Stack
|
|
7
13
|
|
|
8
14
|
- **UI**: Angular 19 standalone + GoA design system (`@abgov/angular-components` — `Goab*` components)
|
|
9
15
|
- **Auth**: `keycloak-angular` with `keycloak-js`
|
|
10
16
|
- **Router**: Angular Router with `createAuthGuard` from `keycloak-angular`
|
|
17
|
+
- **Tests**: Jest
|
|
11
18
|
|
|
12
19
|
## Key files
|
|
13
20
|
|
|
@@ -61,11 +68,22 @@ component wrapper. Use `MutationObserver` to set the property directly after
|
|
|
61
68
|
the inner `<goa-hero-banner>` element appears — see `app.component.ts` for the
|
|
62
69
|
established pattern.
|
|
63
70
|
|
|
64
|
-
##
|
|
71
|
+
## Adding a new route
|
|
72
|
+
|
|
73
|
+
1. Create `src/app/my-feature/my-feature.component.ts` as a standalone component
|
|
74
|
+
2. Add the route to `src/app/app.routes.ts`:
|
|
75
|
+
```typescript
|
|
76
|
+
{ path: 'my-feature', component: MyFeatureComponent }
|
|
77
|
+
// For an authenticated route:
|
|
78
|
+
{ path: 'my-feature', component: MyFeatureComponent, canActivate: [authGuard] }
|
|
79
|
+
```
|
|
80
|
+
3. Add required `Goab*` components to the new component's `imports` array
|
|
65
81
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
## Backend API calls (proxy setup)
|
|
83
|
+
|
|
84
|
+
`includeBearerTokenInterceptor` (configured in `app.config.ts`) automatically
|
|
85
|
+
attaches the Keycloak access token to all outgoing HTTP requests.
|
|
86
|
+
Use relative `/api/` paths — they route through the Angular dev proxy and nginx in production:
|
|
69
87
|
|
|
70
88
|
```typescript
|
|
71
89
|
// ✓ correct — works through proxy in dev, nginx in production
|
|
@@ -75,16 +93,46 @@ this.http.get('/api/v1/my-resource')
|
|
|
75
93
|
this.http.get('http://localhost:3333/my-service/v1/my-resource')
|
|
76
94
|
```
|
|
77
95
|
|
|
78
|
-
|
|
79
|
-
attaches the Keycloak access token to all outgoing HTTP requests.
|
|
80
|
-
In production, `nginx.conf` contains the same proxy rule routing `/api/` to
|
|
81
|
-
the backend service hostname.
|
|
96
|
+
## Testing
|
|
82
97
|
|
|
83
|
-
|
|
98
|
+
Tests live alongside source files (`*.spec.ts`) and run with Jest:
|
|
84
99
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
```bash
|
|
101
|
+
nx test <%= projectName %> # run all tests
|
|
102
|
+
nx test <%= projectName %> --watch # watch mode
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Component test example:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
109
|
+
import { MyFeatureComponent } from './my-feature.component';
|
|
110
|
+
|
|
111
|
+
describe('MyFeatureComponent', () => {
|
|
112
|
+
let fixture: ComponentFixture<MyFeatureComponent>;
|
|
113
|
+
|
|
114
|
+
beforeEach(async () => {
|
|
115
|
+
await TestBed.configureTestingModule({
|
|
116
|
+
imports: [MyFeatureComponent],
|
|
117
|
+
}).compileComponents();
|
|
118
|
+
fixture = TestBed.createComponent(MyFeatureComponent);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('renders', () => {
|
|
122
|
+
fixture.detectChanges();
|
|
123
|
+
expect(fixture.nativeElement.textContent).toContain('Hello');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## OpenShift targets
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
nx run <%= projectName %>:sandbox # build + push to OC internal registry + deploy
|
|
132
|
+
nx run <%= projectName %>:sandbox-teardown # remove sandbox resources
|
|
133
|
+
nx run <%= projectName %>:apply-envs # apply manifests to all environments
|
|
134
|
+
nx run <%= projectName %>:teardown-dev # remove from dev environment
|
|
135
|
+
```
|
|
88
136
|
|
|
89
137
|
## What NOT to change
|
|
90
138
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -11,6 +11,8 @@ export interface AngularAppGeneratorSchema {
|
|
|
11
11
|
proxy?: NginxProxyConfiguration | NginxProxyConfiguration[];
|
|
12
12
|
/** When true, skip the agent interaction. Used by composite generators that run the agent themselves. */
|
|
13
13
|
skipAgent?: boolean;
|
|
14
|
+
/** Name of the paired backend service project, set by composite generators (pean, etc.). */
|
|
15
|
+
pairedProject?: string;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export interface NormalizedSchema extends AngularAppGeneratorSchema {
|
|
@@ -47,7 +47,8 @@ function normalizeOptions(host, options) {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
function addFiles(host, options) {
|
|
50
|
-
|
|
50
|
+
var _a;
|
|
51
|
+
const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), { pairedProject: (_a = options.pairedProject) !== null && _a !== void 0 ? _a : null, tmpl: '' });
|
|
51
52
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files'), options.projectRoot, templateOptions);
|
|
52
53
|
if (options.database === 'postgres' || options.database === 'mongo') {
|
|
53
54
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, `files-${options.database}`), options.projectRoot, templateOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express-service.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/express-service/express-service.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"express-service.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/express-service/express-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Node/Express backend service for the Alberta Digital Service Platform (ADSP).
|
|
4
4
|
Generated by `nx g @abgov/nx-adsp:express-service`.
|
|
5
|
+
<% if (pairedProject) { %>
|
|
6
|
+
## Paired frontend
|
|
5
7
|
|
|
8
|
+
This service is paired with **`<%= pairedProject %>`** — the frontend app it serves.
|
|
9
|
+
The frontend proxies `/api/` to `/<%= projectName %>/` on port 3333 (dev) and via nginx (production).
|
|
10
|
+
When working on a feature that spans both projects, read `apps/<%= pairedProject %>/AGENTS.md` for the frontend context.
|
|
11
|
+
<% } %>
|
|
6
12
|
## Stack
|
|
7
13
|
|
|
8
14
|
- **Runtime**: Node.js + Express
|
|
@@ -10,6 +16,7 @@ Generated by `nx g @abgov/nx-adsp:express-service`.
|
|
|
10
16
|
- **Config**: `envalid` with `.env` file (see `src/environment.ts`)
|
|
11
17
|
- **SDK**: `@abgov/adsp-service-sdk` — provides service registration, auth,
|
|
12
18
|
event publishing, configuration management, and service discovery
|
|
19
|
+
- **Tests**: Jest
|
|
13
20
|
<% if (database === 'postgres') { %>
|
|
14
21
|
- **Database**: PostgreSQL via Prisma ORM
|
|
15
22
|
<% } else if (database === 'mongo') { %>
|
|
@@ -91,8 +98,18 @@ Both `authorize` and `createValidationHandler` pass errors to `next()` —
|
|
|
91
98
|
`createErrorHandler(logger)` at the bottom of `main.ts` translates them to
|
|
92
99
|
structured HTTP responses (401/403 and 400 respectively).
|
|
93
100
|
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
## Adding an environment variable
|
|
102
|
+
|
|
103
|
+
1. Add the variable to `src/environment.ts` using `envalid`:
|
|
104
|
+
```typescript
|
|
105
|
+
MY_SETTING: str({ default: 'default-value', docs: 'Purpose of this setting' }),
|
|
106
|
+
```
|
|
107
|
+
2. Reference it as `environment.MY_SETTING` in your handler
|
|
108
|
+
3. Set the value in `.env` for local development (`.env` is gitignored)
|
|
109
|
+
4. Add it as a ConfigMap entry or Secret ref in the OpenShift deployment manifest
|
|
110
|
+
|
|
111
|
+
Do not read from `process.env` directly — always go through `environment.ts`
|
|
112
|
+
so that missing required values fail loudly at startup.
|
|
96
113
|
<% if (database === 'postgres') { %>
|
|
97
114
|
|
|
98
115
|
## Local database
|
|
@@ -248,15 +265,6 @@ oc create secret generic <app-name>-database \
|
|
|
248
265
|
Domain events are defined in `src/events.ts` and registered at startup via
|
|
249
266
|
`initializeService({ events: [...] })` in `main.ts`.
|
|
250
267
|
|
|
251
|
-
To publish an event from a route handler (use `eventService` from `capabilities`):
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
import { createExampleEvent } from './events';
|
|
255
|
-
|
|
256
|
-
// Inside a route handler, after eventService is in scope via closure:
|
|
257
|
-
await eventService.send(createExampleEvent(id));
|
|
258
|
-
```
|
|
259
|
-
|
|
260
268
|
To add a new event:
|
|
261
269
|
|
|
262
270
|
1. Add a new `const MY_EVENT_NAME` and `DomainEventDefinition` export to `src/events.ts`
|
|
@@ -264,18 +272,47 @@ To add a new event:
|
|
|
264
272
|
3. Add a factory function that returns a typed `DomainEvent`
|
|
265
273
|
4. Call `eventService.send(myFactory(...))` at the appropriate point in your handler
|
|
266
274
|
|
|
267
|
-
##
|
|
275
|
+
## Testing
|
|
276
|
+
|
|
277
|
+
Tests live alongside source files (`*.spec.ts`) and run with Jest:
|
|
268
278
|
|
|
269
|
-
|
|
270
|
-
|
|
279
|
+
```bash
|
|
280
|
+
nx test <%= projectName %> # run all tests
|
|
281
|
+
nx test <%= projectName %> --watch # watch mode
|
|
282
|
+
```
|
|
271
283
|
|
|
272
|
-
|
|
273
|
-
- **Production** (nginx): same rewrite via the nginx proxy block in the frontend app
|
|
284
|
+
Route handler test example:
|
|
274
285
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
286
|
+
```typescript
|
|
287
|
+
import request from 'supertest';
|
|
288
|
+
import express from 'express';
|
|
289
|
+
|
|
290
|
+
describe('GET /<%= projectName %>/v1/items', () => {
|
|
291
|
+
it('returns 200', async () => {
|
|
292
|
+
const app = express();
|
|
293
|
+
app.get('/<%= projectName %>/v1/items', (_req, res) => res.json([]));
|
|
294
|
+
const res = await request(app).get('/<%= projectName %>/v1/items');
|
|
295
|
+
expect(res.status).toBe(200);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
```
|
|
299
|
+
<% if (!pairedProject) { %>
|
|
300
|
+
|
|
301
|
+
## Frontend proxy integration
|
|
302
|
+
|
|
303
|
+
When this service is paired with a React, Angular, or Vue frontend, the frontend
|
|
304
|
+
proxies `/api/` to `/<%= projectName %>/` on port 3333 in development, and via
|
|
305
|
+
nginx in production. All API routes live under `/<%= projectName %>/v1/`.
|
|
306
|
+
<% } %>
|
|
307
|
+
|
|
308
|
+
## OpenShift targets
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
nx run <%= projectName %>:sandbox # build + push to OC internal registry + deploy
|
|
312
|
+
nx run <%= projectName %>:sandbox-teardown # remove sandbox resources
|
|
313
|
+
nx run <%= projectName %>:apply-envs # apply manifests to all environments
|
|
314
|
+
nx run <%= projectName %>:teardown-dev # remove from dev environment
|
|
315
|
+
```
|
|
279
316
|
|
|
280
317
|
## What NOT to change
|
|
281
318
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -14,6 +14,8 @@ export interface Schema {
|
|
|
14
14
|
skipAgent?: boolean;
|
|
15
15
|
/** Database to scaffold. Defaults to 'none'. */
|
|
16
16
|
database?: DatabaseType;
|
|
17
|
+
/** Name of the paired frontend app project, set by composite generators (pevn, pern, pean, etc.). */
|
|
18
|
+
pairedProject?: string;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export interface NormalizedSchema extends Schema {
|
|
@@ -30,11 +30,11 @@ function default_1(host, options) {
|
|
|
30
30
|
const serviceRoot = `${appsDir}/${serviceName}`;
|
|
31
31
|
const appRoot = `${appsDir}/${appName}`;
|
|
32
32
|
// Scaffold both projects before the agent interaction so files exist to upload.
|
|
33
|
-
yield (0, express_service_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: serviceName, skipAgent: true, database: 'postgres' }));
|
|
33
|
+
yield (0, express_service_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: serviceName, skipAgent: true, database: 'postgres', pairedProject: appName }));
|
|
34
34
|
yield (0, angular_app_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: appName, proxy: {
|
|
35
35
|
location: '/api/',
|
|
36
36
|
proxyPass: `http://${serviceName}:3333/${serviceName}/`,
|
|
37
|
-
}, skipAgent: true }));
|
|
37
|
+
}, skipAgent: true, pairedProject: serviceName }));
|
|
38
38
|
if (normalizedOptions.adsp) {
|
|
39
39
|
const accessToken = (_a = normalizedOptions.adsp.accessToken) !== null && _a !== void 0 ? _a : normalizedOptions.accessToken;
|
|
40
40
|
const serviceClientId = `urn:ads:${normalizedOptions.adsp.tenant}:${serviceName}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pean.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pean/pean.ts"],"names":[],"mappings":";;AAoBA,
|
|
1
|
+
{"version":3,"file":"pean.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pean/pean.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,11 +30,11 @@ function default_1(host, options) {
|
|
|
30
30
|
const serviceRoot = `${appsDir}/${serviceName}`;
|
|
31
31
|
const appRoot = `${appsDir}/${appName}`;
|
|
32
32
|
// Scaffold both projects before the agent interaction so files exist to upload.
|
|
33
|
-
yield (0, express_service_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: serviceName, skipAgent: true, database: 'postgres' }));
|
|
33
|
+
yield (0, express_service_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: serviceName, skipAgent: true, database: 'postgres', pairedProject: appName }));
|
|
34
34
|
yield (0, react_app_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: appName, proxy: {
|
|
35
35
|
location: '/api/',
|
|
36
36
|
proxyPass: `http://${serviceName}:3333/${serviceName}/`,
|
|
37
|
-
}, skipAgent: true }));
|
|
37
|
+
}, skipAgent: true, pairedProject: serviceName }));
|
|
38
38
|
if (normalizedOptions.adsp) {
|
|
39
39
|
const accessToken = (_a = normalizedOptions.adsp.accessToken) !== null && _a !== void 0 ? _a : normalizedOptions.accessToken;
|
|
40
40
|
const serviceClientId = `urn:ads:${normalizedOptions.adsp.tenant}:${serviceName}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pern.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pern/pern.ts"],"names":[],"mappings":";;AAoBA,
|
|
1
|
+
{"version":3,"file":"pern.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pern/pern.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,11 +26,11 @@ function default_1(host, options) {
|
|
|
26
26
|
const appsDir = (0, devkit_1.getWorkspaceLayout)(host).appsDir;
|
|
27
27
|
const serviceRoot = `${appsDir}/${serviceName}`;
|
|
28
28
|
const appRoot = `${appsDir}/${appName}`;
|
|
29
|
-
yield (0, express_service_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: serviceName, skipAgent: true, database: 'postgres' }));
|
|
29
|
+
yield (0, express_service_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: serviceName, skipAgent: true, database: 'postgres', pairedProject: appName }));
|
|
30
30
|
yield (0, vue_app_1.default)(host, Object.assign(Object.assign({}, normalizedOptions), { name: appName, proxy: {
|
|
31
31
|
location: '/api/',
|
|
32
32
|
proxyPass: `http://${serviceName}:3333/${serviceName}/`,
|
|
33
|
-
}, skipAgent: true }));
|
|
33
|
+
}, skipAgent: true, pairedProject: serviceName }));
|
|
34
34
|
if (normalizedOptions.adsp) {
|
|
35
35
|
const accessToken = (_a = normalizedOptions.adsp.accessToken) !== null && _a !== void 0 ? _a : normalizedOptions.accessToken;
|
|
36
36
|
const serviceClientId = `urn:ads:${normalizedOptions.adsp.tenant}:${serviceName}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pevn.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pevn/pevn.ts"],"names":[],"mappings":";;AAiBA,
|
|
1
|
+
{"version":3,"file":"pevn.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pevn/pevn.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
React frontend for the Alberta Digital Service Platform (ADSP).
|
|
4
4
|
Generated by `nx g @abgov/nx-adsp:react-app`.
|
|
5
|
+
<% if (pairedProject) { %>
|
|
6
|
+
## Paired service
|
|
5
7
|
|
|
8
|
+
This app is paired with **`<%= pairedProject %>`** — the Express backend it talks to.
|
|
9
|
+
API calls use the `/api/` prefix which the webpack dev proxy rewrites to `/<%= pairedProject %>/` on port 3333.
|
|
10
|
+
When working on a feature that spans both projects, read `apps/<%= pairedProject %>/AGENTS.md` for the service context.
|
|
11
|
+
<% } %>
|
|
6
12
|
## Stack
|
|
7
13
|
|
|
8
14
|
- **UI**: React 18 + GoA design system (`@abgov/react-components` — `Goab*` components)
|
|
9
15
|
- **Auth**: `keycloak-js` via Redux Toolkit slice (`src/app/user.slice.ts`)
|
|
10
16
|
- **State**: Redux Toolkit — store in `src/store.ts`
|
|
11
17
|
- **Router**: React Router v6
|
|
18
|
+
- **Tests**: Jest + React Testing Library
|
|
12
19
|
|
|
13
20
|
## Key files
|
|
14
21
|
|
|
@@ -44,16 +51,35 @@ Components are imported from `@abgov/react-components` with the `Goab` prefix:
|
|
|
44
51
|
import { GoabButton, GoabAppHeader, GoabButtonGroup } from '@abgov/react-components';
|
|
45
52
|
```
|
|
46
53
|
|
|
54
|
+
**Event names**: GoA React components use `onGoab*` handlers (not standard React synthetic events):
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<GoabButton onGoabClick={handleSave}>Save</GoabButton>
|
|
58
|
+
<GoabInput onGoabChange={(e) => setValue(e.detail.value)} />
|
|
59
|
+
<GoabDropdown onGoabChange={(e) => setSelected(e.detail.value)} />
|
|
60
|
+
<GoabCheckbox onGoabChange={(e) => setChecked(e.detail.checked)} />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Event detail shapes vary by component — check the `detail` type in `@abgov/react-components`.
|
|
64
|
+
See [GoA web components docs](https://ui-components.alberta.ca) for the full component reference.
|
|
65
|
+
|
|
66
|
+
## Adding a new route
|
|
67
|
+
|
|
68
|
+
1. Create `src/app/my-feature/MyFeature.tsx` as a React component
|
|
69
|
+
2. Add the route to the router in `src/app/app.tsx`:
|
|
70
|
+
```tsx
|
|
71
|
+
<Route path="/my-feature" element={<MyFeature />} />
|
|
72
|
+
```
|
|
73
|
+
3. Add a nav link to the app shell if needed
|
|
74
|
+
|
|
47
75
|
## Adding a new Redux slice
|
|
48
76
|
|
|
49
77
|
1. Create `src/app/my-feature.slice.ts` using `createSlice` / `createAsyncThunk`
|
|
50
78
|
2. Export the reducer and add it to `src/store.ts`
|
|
51
79
|
|
|
52
|
-
## Backend API calls (
|
|
80
|
+
## Backend API calls (proxy setup)
|
|
53
81
|
|
|
54
|
-
|
|
55
|
-
backend service in development. Use relative `/api/` paths — do not hardcode
|
|
56
|
-
the service URL:
|
|
82
|
+
Use relative `/api/` paths — they route through the webpack dev proxy and nginx in production:
|
|
57
83
|
|
|
58
84
|
```typescript
|
|
59
85
|
// ✓ correct — works through proxy in dev, nginx in production
|
|
@@ -63,8 +89,39 @@ const response = await fetch('/api/v1/my-resource');
|
|
|
63
89
|
const response = await fetch('http://localhost:3333/my-service/v1/my-resource');
|
|
64
90
|
```
|
|
65
91
|
|
|
66
|
-
|
|
67
|
-
|
|
92
|
+
## Testing
|
|
93
|
+
|
|
94
|
+
Tests live alongside source files (`*.spec.tsx`) and run with Jest:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
nx test <%= projectName %> # run all tests
|
|
98
|
+
nx test <%= projectName %> --watch # watch mode
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Component test example:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { render, screen } from '@testing-library/react';
|
|
105
|
+
import { Provider } from 'react-redux';
|
|
106
|
+
import { store } from '../../store';
|
|
107
|
+
import MyFeature from './MyFeature';
|
|
108
|
+
|
|
109
|
+
describe('MyFeature', () => {
|
|
110
|
+
it('renders correctly', () => {
|
|
111
|
+
render(<Provider store={store}><MyFeature /></Provider>);
|
|
112
|
+
expect(screen.getByText('Hello')).toBeInTheDocument();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## OpenShift targets
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
nx run <%= projectName %>:sandbox # build + push to OC internal registry + deploy
|
|
121
|
+
nx run <%= projectName %>:sandbox-teardown # remove sandbox resources
|
|
122
|
+
nx run <%= projectName %>:apply-envs # apply manifests to all environments
|
|
123
|
+
nx run <%= projectName %>:teardown-dev # remove from dev environment
|
|
124
|
+
```
|
|
68
125
|
|
|
69
126
|
## What NOT to change
|
|
70
127
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -29,7 +29,8 @@ function normalizeOptions(host, options) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
function addFiles(host, options) {
|
|
32
|
-
|
|
32
|
+
var _a;
|
|
33
|
+
const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), { pairedProject: (_a = options.pairedProject) !== null && _a !== void 0 ? _a : null, tmpl: '' });
|
|
33
34
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files'), options.projectRoot, templateOptions);
|
|
34
35
|
const addProxyConf = options.nginxProxies.length > 0;
|
|
35
36
|
if (addProxyConf) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-app.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/react-app/react-app.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"react-app.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/react-app/react-app.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ export interface Schema {
|
|
|
11
11
|
proxy?: NginxProxyConfiguration | NginxProxyConfiguration[];
|
|
12
12
|
/** When true, skip the agent interaction. Used by composite generators that run the agent themselves. */
|
|
13
13
|
skipAgent?: boolean;
|
|
14
|
+
/** Name of the paired backend service project, set by composite generators (pern, etc.). */
|
|
15
|
+
pairedProject?: string;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export interface NormalizedSchema extends Schema {
|
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Vue 3 frontend for the Alberta Digital Service Platform (ADSP).
|
|
4
4
|
Generated by `nx g @abgov/nx-adsp:vue-app`.
|
|
5
|
+
<% if (pairedProject) { %>
|
|
6
|
+
## Paired service
|
|
5
7
|
|
|
8
|
+
This app is paired with **`<%= pairedProject %>`** — the Express backend it talks to.
|
|
9
|
+
API calls use the `/api/` prefix which the Vite dev proxy rewrites to `/<%= pairedProject %>/` on port 3333.
|
|
10
|
+
When working on a feature that spans both projects, read `apps/<%= pairedProject %>/AGENTS.md` for the service context.
|
|
11
|
+
<% } %>
|
|
6
12
|
## Stack
|
|
7
13
|
|
|
8
14
|
- **UI**: Vue 3 (Composition API) + GoA design system (`@abgov/web-components` — `goa-*` custom elements)
|
|
9
15
|
- **Auth**: `@dsb-norge/vue-keycloak-js` (wraps `keycloak-js`)
|
|
10
16
|
- **State**: Pinia
|
|
11
17
|
- **Router**: Vue Router v4
|
|
18
|
+
- **Tests**: Vitest
|
|
12
19
|
|
|
13
20
|
## Key files
|
|
14
21
|
|
|
@@ -65,18 +72,31 @@ router.beforeEach((to) => {
|
|
|
65
72
|
Use `goa-*` web components directly in Vue templates. The vite.config.ts
|
|
66
73
|
`isCustomElement` option prevents Vue from warning about unknown elements.
|
|
67
74
|
|
|
68
|
-
**Event names**: GoA web component interactive elements
|
|
69
|
-
|
|
70
|
-
events. Use `@_click` in Vue templates:
|
|
75
|
+
**Event names**: GoA web component interactive elements emit custom events with
|
|
76
|
+
a `_` prefix to avoid conflicts with native browser events:
|
|
71
77
|
|
|
72
78
|
```html
|
|
73
79
|
<goa-button type="primary" @_click="handleSave">Save</goa-button>
|
|
74
80
|
<goa-input @_change="handleChange" />
|
|
81
|
+
<goa-dropdown @_change="handleSelect" />
|
|
82
|
+
<goa-checkbox @_change="handleCheck" />
|
|
75
83
|
```
|
|
76
84
|
|
|
85
|
+
Use `@_click` for buttons and `@_change` for inputs, dropdowns, and checkboxes.
|
|
77
86
|
See [GoA web components docs](https://ui-components.alberta.ca) for the full
|
|
78
87
|
component and event reference.
|
|
79
88
|
|
|
89
|
+
## Adding a view
|
|
90
|
+
|
|
91
|
+
1. Create `src/views/MyFeatureView.vue` as a `<script setup>` SFC
|
|
92
|
+
2. Add the route to `src/router/index.ts`:
|
|
93
|
+
```typescript
|
|
94
|
+
{ path: '/my-feature', component: () => import('../views/MyFeatureView.vue') }
|
|
95
|
+
// For an authenticated route:
|
|
96
|
+
{ path: '/my-feature', component: () => import('../views/MyFeatureView.vue'), meta: { requiresAuth: true } }
|
|
97
|
+
```
|
|
98
|
+
3. Add a nav link to `src/App.vue` if needed
|
|
99
|
+
|
|
80
100
|
## Backend API calls (proxy setup)
|
|
81
101
|
|
|
82
102
|
Use relative `/api/` paths — they route through Vite's dev proxy and nginx in production:
|
|
@@ -89,6 +109,39 @@ const res = await fetch('/api/v1/my-resource');
|
|
|
89
109
|
const res = await fetch('http://localhost:3333/my-service/v1/my-resource');
|
|
90
110
|
```
|
|
91
111
|
|
|
112
|
+
## Testing
|
|
113
|
+
|
|
114
|
+
Tests live alongside source files (`*.spec.ts` / `*.spec.vue`) and run with Vitest:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
nx test <%= projectName %> # run all tests
|
|
118
|
+
nx test <%= projectName %> --watch # watch mode
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Component test example:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { mount } from '@vue/test-utils';
|
|
125
|
+
import { describe, it, expect } from 'vitest';
|
|
126
|
+
import MyComponent from './MyComponent.vue';
|
|
127
|
+
|
|
128
|
+
describe('MyComponent', () => {
|
|
129
|
+
it('renders correctly', () => {
|
|
130
|
+
const wrapper = mount(MyComponent, { props: { title: 'Hello' } });
|
|
131
|
+
expect(wrapper.text()).toContain('Hello');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## OpenShift targets
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
nx run <%= projectName %>:sandbox # build + push to OC internal registry + deploy
|
|
140
|
+
nx run <%= projectName %>:sandbox-teardown # remove sandbox resources
|
|
141
|
+
nx run <%= projectName %>:apply-envs # apply manifests to all environments
|
|
142
|
+
nx run <%= projectName %>:teardown-dev # remove from dev environment
|
|
143
|
+
```
|
|
144
|
+
|
|
92
145
|
## What NOT to change
|
|
93
146
|
|
|
94
147
|
- `src/main.ts` — Keycloak plugin is registered once here; do not call `new Keycloak()` elsewhere
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -11,6 +11,8 @@ export interface Schema {
|
|
|
11
11
|
proxy?: NginxProxyConfiguration | NginxProxyConfiguration[];
|
|
12
12
|
/** When true, skip the agent interaction. Used by composite generators that run the agent themselves. */
|
|
13
13
|
skipAgent?: boolean;
|
|
14
|
+
/** Name of the paired backend service project, set by composite generators (pevn, etc.). */
|
|
15
|
+
pairedProject?: string;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export interface NormalizedSchema extends Schema {
|
|
@@ -24,7 +24,8 @@ function normalizeOptions(host, options) {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
function addFiles(host, options) {
|
|
27
|
-
|
|
27
|
+
var _a;
|
|
28
|
+
const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), { offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.projectRoot), pairedProject: (_a = options.pairedProject) !== null && _a !== void 0 ? _a : null, tmpl: '' });
|
|
28
29
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files'), options.projectRoot, templateOptions);
|
|
29
30
|
const addProxyConf = options.nginxProxies.length > 0;
|
|
30
31
|
if (addProxyConf) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue-app.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/vue-app/vue-app.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"vue-app.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/vue-app/vue-app.ts"],"names":[],"mappings":"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"}
|