@nivora/matrix 0.1.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.
Potentially problematic release.
This version of @nivora/matrix might be problematic. Click here for more details.
- package/.next/BUILD_ID +1 -0
- package/.next/app-path-routes-manifest.json +12 -0
- package/.next/build-manifest.json +20 -0
- package/.next/diagnostics/build-diagnostics.json +6 -0
- package/.next/diagnostics/framework.json +1 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +66 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +90 -0
- package/.next/react-loadable-manifest.json +1 -0
- package/.next/required-server-files.js +165 -0
- package/.next/required-server-files.json +165 -0
- package/.next/routes-manifest.json +109 -0
- package/.next/server/app/_global-error/page.js +3 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_global-error.html +2 -0
- package/.next/server/app/_global-error.meta +16 -0
- package/.next/server/app/_global-error.rsc +12 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +12 -0
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +4 -0
- package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_index.segment.rsc +4 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page.js +2 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_not-found.html +1 -0
- package/.next/server/app/_not-found.meta +16 -0
- package/.next/server/app/_not-found.rsc +15 -0
- package/.next/server/app/_not-found.segments/_full.segment.rsc +15 -0
- package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_index.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +4 -0
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
- package/.next/server/app/builder/page.js +24 -0
- package/.next/server/app/builder/page.js.nft.json +1 -0
- package/.next/server/app/builder/page_client-reference-manifest.js +1 -0
- package/.next/server/app/favicon.ico/route.js +1 -0
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -0
- package/.next/server/app/favicon.ico.body +0 -0
- package/.next/server/app/favicon.ico.meta +1 -0
- package/.next/server/app/guide/page.js +2 -0
- package/.next/server/app/guide/page.js.nft.json +1 -0
- package/.next/server/app/guide/page_client-reference-manifest.js +1 -0
- package/.next/server/app/matrix/page.js +2 -0
- package/.next/server/app/matrix/page.js.nft.json +1 -0
- package/.next/server/app/matrix/page_client-reference-manifest.js +1 -0
- package/.next/server/app/page.js +2 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app/releases/[id]/page.js +51 -0
- package/.next/server/app/releases/[id]/page.js.nft.json +1 -0
- package/.next/server/app/releases/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/releases/page.js +34 -0
- package/.next/server/app/releases/page.js.nft.json +1 -0
- package/.next/server/app/releases/page_client-reference-manifest.js +1 -0
- package/.next/server/app/specs/[id]/page.js +2 -0
- package/.next/server/app/specs/[id]/page.js.nft.json +1 -0
- package/.next/server/app/specs/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +12 -0
- package/.next/server/chunks/13.js +1 -0
- package/.next/server/chunks/135.js +34 -0
- package/.next/server/chunks/390.js +1 -0
- package/.next/server/chunks/445.js +22 -0
- package/.next/server/chunks/471.js +13 -0
- package/.next/server/chunks/476.js +23 -0
- package/.next/server/chunks/530.js +72 -0
- package/.next/server/chunks/870.js +1 -0
- package/.next/server/functions-config-manifest.json +4 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/404.html +1 -0
- package/.next/server/pages/500.html +2 -0
- package/.next/server/pages-manifest.json +4 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/8ZUFcYHRSRlY1FYWZ33gH/_buildManifest.js +1 -0
- package/.next/static/8ZUFcYHRSRlY1FYWZ33gH/_ssgManifest.js +1 -0
- package/.next/static/chunks/4bd1b696-67e30520d621c4dd.js +1 -0
- package/.next/static/chunks/500-b84d19d842172eba.js +1 -0
- package/.next/static/chunks/794-9353bb3ab9a73e90.js +2 -0
- package/.next/static/chunks/app/_global-error/page-aba28f88d5781771.js +1 -0
- package/.next/static/chunks/app/_not-found/page-90fe62e7982fba87.js +1 -0
- package/.next/static/chunks/app/builder/page-e10754eb65a4f784.js +10 -0
- package/.next/static/chunks/app/guide/page-9c9dff9c5e3ddefe.js +1 -0
- package/.next/static/chunks/app/layout-550e25f5579f1a32.js +1 -0
- package/.next/static/chunks/app/matrix/page-b2418abb52a7acd8.js +1 -0
- package/.next/static/chunks/app/page-9c9dff9c5e3ddefe.js +1 -0
- package/.next/static/chunks/app/releases/[id]/page-d8069a1802686478.js +1 -0
- package/.next/static/chunks/app/releases/page-26a520d9789e69f5.js +1 -0
- package/.next/static/chunks/app/specs/[id]/page-7065af5d4d103f16.js +1 -0
- package/.next/static/chunks/framework-d7de93249215fb06.js +1 -0
- package/.next/static/chunks/main-17e3a04cf2f94dca.js +5 -0
- package/.next/static/chunks/main-app-6d93e914b4a54c7e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-aba28f88d5781771.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-aba28f88d5781771.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/global-error-ebbdf863aa6a4349.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-aba28f88d5781771.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-aba28f88d5781771.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-650bc85863e2a9e7.js +1 -0
- package/.next/static/css/f29e518c867dffaa.css +1 -0
- package/.next/trace-build +1 -0
- package/.next/types/app/builder/page.ts +86 -0
- package/.next/types/app/guide/page.ts +86 -0
- package/.next/types/app/layout.ts +86 -0
- package/.next/types/app/matrix/page.ts +86 -0
- package/.next/types/app/page.ts +86 -0
- package/.next/types/app/releases/[id]/page.ts +86 -0
- package/.next/types/app/releases/page.ts +86 -0
- package/.next/types/app/specs/[id]/page.ts +86 -0
- package/.next/types/package.json +1 -0
- package/.next/types/routes.d.ts +63 -0
- package/.next/types/validator.ts +115 -0
- package/README.md +185 -0
- package/bin/cli.js +3650 -0
- package/bin/cli.ts +170 -0
- package/next.config.ts +11 -0
- package/package.json +59 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// This file is generated automatically by Next.js
|
|
2
|
+
// Do not edit this file manually
|
|
3
|
+
// This file validates that all pages and layouts export the correct types
|
|
4
|
+
|
|
5
|
+
import type { AppRoutes, LayoutRoutes, ParamMap } from "./routes.js"
|
|
6
|
+
import type { ResolvingMetadata, ResolvingViewport } from "next/types.js"
|
|
7
|
+
|
|
8
|
+
type AppPageConfig<Route extends AppRoutes = AppRoutes> = {
|
|
9
|
+
default: React.ComponentType<{ params: Promise<ParamMap[Route]> } & any> | ((props: { params: Promise<ParamMap[Route]> } & any) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
|
|
10
|
+
generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
|
|
11
|
+
generateMetadata?: (
|
|
12
|
+
props: { params: Promise<ParamMap[Route]> } & any,
|
|
13
|
+
parent: ResolvingMetadata
|
|
14
|
+
) => Promise<any> | any
|
|
15
|
+
generateViewport?: (
|
|
16
|
+
props: { params: Promise<ParamMap[Route]> } & any,
|
|
17
|
+
parent: ResolvingViewport
|
|
18
|
+
) => Promise<any> | any
|
|
19
|
+
metadata?: any
|
|
20
|
+
viewport?: any
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type LayoutConfig<Route extends LayoutRoutes = LayoutRoutes> = {
|
|
24
|
+
default: React.ComponentType<LayoutProps<Route>> | ((props: LayoutProps<Route>) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
|
|
25
|
+
generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
|
|
26
|
+
generateMetadata?: (
|
|
27
|
+
props: { params: Promise<ParamMap[Route]> } & any,
|
|
28
|
+
parent: ResolvingMetadata
|
|
29
|
+
) => Promise<any> | any
|
|
30
|
+
generateViewport?: (
|
|
31
|
+
props: { params: Promise<ParamMap[Route]> } & any,
|
|
32
|
+
parent: ResolvingViewport
|
|
33
|
+
) => Promise<any> | any
|
|
34
|
+
metadata?: any
|
|
35
|
+
viewport?: any
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// Validate ../../src/app/builder/page.tsx
|
|
40
|
+
{
|
|
41
|
+
type __IsExpected<Specific extends AppPageConfig<"/builder">> = Specific
|
|
42
|
+
const handler = {} as typeof import("../../src/app/builder/page.js")
|
|
43
|
+
type __Check = __IsExpected<typeof handler>
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
type __Unused = __Check
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Validate ../../src/app/guide/page.tsx
|
|
49
|
+
{
|
|
50
|
+
type __IsExpected<Specific extends AppPageConfig<"/guide">> = Specific
|
|
51
|
+
const handler = {} as typeof import("../../src/app/guide/page.js")
|
|
52
|
+
type __Check = __IsExpected<typeof handler>
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
type __Unused = __Check
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Validate ../../src/app/matrix/page.tsx
|
|
58
|
+
{
|
|
59
|
+
type __IsExpected<Specific extends AppPageConfig<"/matrix">> = Specific
|
|
60
|
+
const handler = {} as typeof import("../../src/app/matrix/page.js")
|
|
61
|
+
type __Check = __IsExpected<typeof handler>
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
type __Unused = __Check
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Validate ../../src/app/page.tsx
|
|
67
|
+
{
|
|
68
|
+
type __IsExpected<Specific extends AppPageConfig<"/">> = Specific
|
|
69
|
+
const handler = {} as typeof import("../../src/app/page.js")
|
|
70
|
+
type __Check = __IsExpected<typeof handler>
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
type __Unused = __Check
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Validate ../../src/app/releases/[id]/page.tsx
|
|
76
|
+
{
|
|
77
|
+
type __IsExpected<Specific extends AppPageConfig<"/releases/[id]">> = Specific
|
|
78
|
+
const handler = {} as typeof import("../../src/app/releases/[id]/page.js")
|
|
79
|
+
type __Check = __IsExpected<typeof handler>
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
type __Unused = __Check
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Validate ../../src/app/releases/page.tsx
|
|
85
|
+
{
|
|
86
|
+
type __IsExpected<Specific extends AppPageConfig<"/releases">> = Specific
|
|
87
|
+
const handler = {} as typeof import("../../src/app/releases/page.js")
|
|
88
|
+
type __Check = __IsExpected<typeof handler>
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
type __Unused = __Check
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Validate ../../src/app/specs/[id]/page.tsx
|
|
94
|
+
{
|
|
95
|
+
type __IsExpected<Specific extends AppPageConfig<"/specs/[id]">> = Specific
|
|
96
|
+
const handler = {} as typeof import("../../src/app/specs/[id]/page.js")
|
|
97
|
+
type __Check = __IsExpected<typeof handler>
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
type __Unused = __Check
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// Validate ../../src/app/layout.tsx
|
|
109
|
+
{
|
|
110
|
+
type __IsExpected<Specific extends LayoutConfig<"/">> = Specific
|
|
111
|
+
const handler = {} as typeof import("../../src/app/layout.js")
|
|
112
|
+
type __Check = __IsExpected<typeof handler>
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
type __Unused = __Check
|
|
115
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# GAMP 5 V-Model Traceability System
|
|
2
|
+
|
|
3
|
+
A streamlined requirements traceability and test management system designed for regulated environments, using **Gherkin as the source of truth** for Functional Specifications.
|
|
4
|
+
|
|
5
|
+
📚 **Documentation**:
|
|
6
|
+
- [**User Guide**](./USER_GUIDE.md): How to use the dashboard and CLI.
|
|
7
|
+
- [**Developer Guide**](./DEVELOPER_GUIDE.md): Architecture, setup, and development workflow.
|
|
8
|
+
- [**Philosophy & Approach**](./GAMP_AND_V_MODEL.md): GAMP 5 principles, V-Model, and "Spec-as-Code" reasoning.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Data Model
|
|
12
|
+
|
|
13
|
+
This system uses a **relational model** with 3 artifact types and no duplicate data:
|
|
14
|
+
|
|
15
|
+
| Artifact | Format | Location | Purpose |
|
|
16
|
+
|----------|--------|----------|---------|
|
|
17
|
+
| **URS** | Database | SQLite Table `urs` | High-level business requirements |
|
|
18
|
+
| **FS** | Gherkin | `specs/fs/*.requirement` | Functional specs + embedded test scenarios |
|
|
19
|
+
| **RISK** | Database | SQLite Table `risks` | Risk assessments linked to FS |
|
|
20
|
+
|
|
21
|
+
### Key Insight: Gherkin IS the Functional Specification
|
|
22
|
+
|
|
23
|
+
Instead of maintaining separate FS documents and test files, we use Gherkin Feature files AS the functional specification:
|
|
24
|
+
|
|
25
|
+
```gherkin
|
|
26
|
+
@URS-001 @RISK-001
|
|
27
|
+
Feature: FS-001 User Login Authentication
|
|
28
|
+
The system shall provide a login interface that authenticates users
|
|
29
|
+
against stored credentials and establishes a secure session.
|
|
30
|
+
|
|
31
|
+
Requirements:
|
|
32
|
+
- FR-001.1: Display login form with email and password fields
|
|
33
|
+
- FR-001.2: Validate credentials against stored hash
|
|
34
|
+
- FR-001.3: Rate limit after 5 failed attempts
|
|
35
|
+
|
|
36
|
+
Scenario: Successful login with valid credentials
|
|
37
|
+
Given I am on the login page
|
|
38
|
+
When I enter valid credentials
|
|
39
|
+
Then I should be redirected to my dashboard
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Benefits:**
|
|
43
|
+
- **No duplication**: The Feature description IS the spec, scenarios ARE the tests
|
|
44
|
+
- **Single source of truth**: Edit one file, both spec and tests are updated
|
|
45
|
+
- **Clear traceability**: `@URS-xxx` and `@RISK-xxx` tags create automatic links
|
|
46
|
+
- **Executable specs**: The `.requirement` files can be run by Cucumber
|
|
47
|
+
|
|
48
|
+
## Directory Structure
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
docs/
|
|
52
|
+
├── specs/
|
|
53
|
+
│ └── fs/ # Functional Specs (Gherkin)
|
|
54
|
+
│ ├── FS-001-login.requirement
|
|
55
|
+
│ ├── FS-002-session.requirement
|
|
56
|
+
│ ├── FS-003-registration.requirement
|
|
57
|
+
│ ├── FS-004-booking.requirement
|
|
58
|
+
│ ├── FS-005-waitlist.requirement
|
|
59
|
+
│ ├── FS-006-schedule.requirement
|
|
60
|
+
│ └── FS-007-instructor.requirement
|
|
61
|
+
└── src/ # Next.js Dashboard
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Linking Artifacts
|
|
65
|
+
|
|
66
|
+
### URS to FS
|
|
67
|
+
Use `@URS-xxx` tag in the Gherkin Feature:
|
|
68
|
+
```gherkin
|
|
69
|
+
@URS-001
|
|
70
|
+
Feature: FS-001 User Login
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### FS to Risk
|
|
74
|
+
Use `@RISK-xxx` tag in the Gherkin Feature:
|
|
75
|
+
```gherkin
|
|
76
|
+
@URS-001 @RISK-001
|
|
77
|
+
Feature: FS-001 User Login
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Verification Levels (V-Model)
|
|
81
|
+
- **URS** → Verified by **PQ** (Performance Qualification)
|
|
82
|
+
- **FS** → Verified by **OQ** (Operational Qualification)
|
|
83
|
+
- **Scenarios** → Verified by **IQ** (Installation Qualification)
|
|
84
|
+
|
|
85
|
+
## Running the Dashboard
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
cd docs
|
|
89
|
+
bun install
|
|
90
|
+
bun run dev
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Access at: http://localhost:3000
|
|
94
|
+
|
|
95
|
+
## Dashboard Pages
|
|
96
|
+
|
|
97
|
+
| Page | Description |
|
|
98
|
+
|------|-------------|
|
|
99
|
+
| `/` | Dashboard with stats, coverage, and traceability summary |
|
|
100
|
+
| `/specs` | Browse URS (YAML), FS (Gherkin), and Risk (YAML) |
|
|
101
|
+
| `/matrix` | Full traceability matrix: URS → FS → Scenarios → Risks |
|
|
102
|
+
| `/builder` | Visual editor for creating new FS .requirement files |
|
|
103
|
+
| `/search` | Search across all artifacts |
|
|
104
|
+
|
|
105
|
+
## Creating New Artifacts
|
|
106
|
+
|
|
107
|
+
### New URS (via Dashboard or manually)
|
|
108
|
+
Create `specs/urs/URS-xxx.yaml`:
|
|
109
|
+
```yaml
|
|
110
|
+
id: URS-004
|
|
111
|
+
type: urs
|
|
112
|
+
title: New Business Requirement
|
|
113
|
+
status: draft
|
|
114
|
+
priority: high
|
|
115
|
+
owner: Product Team
|
|
116
|
+
category: Core
|
|
117
|
+
business_need: |
|
|
118
|
+
Description of the business need...
|
|
119
|
+
intended_use: |
|
|
120
|
+
How the system will be used...
|
|
121
|
+
acceptance_criteria:
|
|
122
|
+
- Criterion 1
|
|
123
|
+
- Criterion 2
|
|
124
|
+
regulatory_refs:
|
|
125
|
+
- GAMP 5
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### New FS (via Builder or manually)
|
|
129
|
+
Create `specs/fs/FS-xxx-name.requirement`:
|
|
130
|
+
```gherkin
|
|
131
|
+
@URS-xxx @RISK-xxx
|
|
132
|
+
Feature: FS-xxx Feature Title
|
|
133
|
+
The system shall...
|
|
134
|
+
|
|
135
|
+
Requirements:
|
|
136
|
+
- FR-xxx.1: First requirement
|
|
137
|
+
- FR-xxx.2: Second requirement
|
|
138
|
+
|
|
139
|
+
Scenario: Test case 1
|
|
140
|
+
Given ...
|
|
141
|
+
When ...
|
|
142
|
+
Then ...
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### New Risk (manually)
|
|
146
|
+
Create `specs/risk/RISK-xxx.yaml`:
|
|
147
|
+
```yaml
|
|
148
|
+
id: RISK-004
|
|
149
|
+
type: risk
|
|
150
|
+
title: Risk Title
|
|
151
|
+
status: draft
|
|
152
|
+
category: Security
|
|
153
|
+
gamp_category: 4
|
|
154
|
+
fs_ids:
|
|
155
|
+
- FS-001
|
|
156
|
+
impact: high
|
|
157
|
+
probability: medium
|
|
158
|
+
risk_level: high
|
|
159
|
+
risks:
|
|
160
|
+
- id: R-004.1
|
|
161
|
+
description: Risk description
|
|
162
|
+
impact: high
|
|
163
|
+
probability: medium
|
|
164
|
+
mitigations:
|
|
165
|
+
- risk_id: R-004.1
|
|
166
|
+
control: Control measure
|
|
167
|
+
test: How to test
|
|
168
|
+
residual_risk: acceptable
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Running Tests
|
|
172
|
+
|
|
173
|
+
The `.requirement` files are standard Gherkin and can be executed with Cucumber:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Configure cucumber to find .requirement files
|
|
177
|
+
npx cucumber-js specs/fs/**/*.requirement
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## GAMP 5 Compliance
|
|
181
|
+
|
|
182
|
+
- **Category 4**: Configured products (authentication, session management)
|
|
183
|
+
- **Category 5**: Custom applications (booking transactions)
|
|
184
|
+
- **21 CFR Part 11**: Electronic records and signatures ready
|
|
185
|
+
- **ALCOA+**: Data integrity principles for booking records
|