Skip to content

Commit fac197f

Browse files
add copilot instructions + update codeowners
1 parent 13f0679 commit fac197f

File tree

2 files changed

+283
-1
lines changed

2 files changed

+283
-1
lines changed

.github/.copilot-instructions.md

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
# GitHub Copilot Instructions for StatusBoard
2+
3+
## Project Overview
4+
StatusBoard is a real-time monitoring platform for tracking service health status. It features:
5+
- HTTP and AWS SDK-based health checks
6+
- Status change history tracking
7+
- Email and MS Teams notifications
8+
- REST API for programmatic access
9+
- Angular-based UI for visualization
10+
11+
## Technology Stack
12+
13+
### Backend (Scala)
14+
- **Framework**: ZIO (functional effects library)
15+
- **Build Tool**: SBT (Scala Build Tool)
16+
- **API**: Tapir for type-safe HTTP endpoints with Swagger documentation
17+
- **HTTP Server**: Blaze Server (http4s)
18+
- **Database**: AWS DynamoDB for persistence
19+
- **Testing**: ZIO Test framework
20+
- **Code Coverage**: Jacoco
21+
22+
### Frontend (TypeScript)
23+
- **Framework**: Angular 19
24+
- **UI Library**: PrimeNG, CPS UI Kit
25+
- **Testing**: Jest (unit tests) with `jest.config.ts`, Cypress (e2e tests) with `cypress.json`
26+
- **Build Tool**: Angular CLI
27+
- **Styling**: SCSS
28+
29+
### Infrastructure
30+
- **Runtime**: JRE 21 (Corretto)
31+
- **Containerization**: Docker with docker-compose
32+
- **Cloud**: AWS (DynamoDB, SDK integrations)
33+
34+
## Code Style and Conventions
35+
36+
### Scala Code
37+
- Follow functional programming principles with ZIO effects
38+
- Use `scalafmt` for code formatting (`.scalafmt.conf` is configured)
39+
- Enable compiler flags: `-unchecked`, `-deprecation`, `-feature`, `-Xfatal-warnings`, `-Ymacro-annotations`
40+
- Organize code into layers:
41+
- **Controllers**: Business logic and API endpoint handlers
42+
- **Repository**: Database access layer
43+
- **Services**: Core business services (monitoring, notifications)
44+
- **Checkers**: Health check implementations
45+
- **Models**: Domain models and DTOs
46+
- **Config**: Configuration management with ZIO Config
47+
48+
### TypeScript/Angular Code
49+
- Use ESLint (via `eslint.config.js`) and Prettier (via `.prettierrc`) for linting and formatting
50+
- Follow Angular style guide
51+
- Component-based architecture with services for business logic
52+
- Use RxJS for reactive programming
53+
- Test with Jest and Cypress
54+
55+
### Error Handling
56+
- Use ZIO's `IO[ErrorResponse, A]` pattern for typed errors
57+
- Map database errors to API response errors consistently
58+
- Common error types: `RecordNotFoundErrorResponse`, `DataConflictErrorResponse`, `InternalServerErrorResponse`, `UnauthorizedErrorResponse`
59+
60+
### Authentication
61+
- API key-based authentication via `Authorization` header
62+
- Use `AuthController` ([api/controllers/AuthController.scala](../src/main/scala/za/co/absa/statusboard/api/controllers/AuthController.scala)) to protect write endpoints
63+
- Read endpoints are generally public
64+
65+
## Project Structure
66+
67+
### Backend (`src/main/scala`)
68+
```
69+
za. co.absa.statusboard/
70+
├── api/
71+
│ ├── controllers/ # API endpoint handlers
72+
│ │ ├── AuthController
73+
│ │ ├── ServiceConfigurationController
74+
│ │ ├── StatusController
75+
│ │ └── MonitoringController
76+
│ └── http/ # HTTP layer (routes, endpoints)
77+
├── checker/ # Health check implementations
78+
├── config/ # Configuration models
79+
├── model/ # Domain models
80+
├── monitoring/ # Monitoring service and workers
81+
├── notification/ # Email and Teams notifications
82+
├── providers/ # External service providers
83+
└── repository/ # Database access layer
84+
```
85+
86+
### Frontend (`ui/src/app`)
87+
```
88+
├── components/ # Angular components
89+
│ ├── status-list/
90+
│ ├── status-history/
91+
│ ├── card/
92+
│ └── dependency-graph/
93+
├── services/ # Angular services
94+
│ ├── backend/ # API client
95+
│ ├── repository/ # Data management
96+
│ └── refresh/ # Auto-refresh logic
97+
└── modules/ # Shared modules
98+
```
99+
100+
## Key Patterns
101+
102+
### ZIO Layers
103+
- Use ZIO layers for dependency injection
104+
- Define layer in companion object: `object XImpl { val layer: TaskLayer[X] = ... }`
105+
- Access services via ZIO environment: `ZIO.serviceWithZIO[Service](_. method())`
106+
107+
### API Endpoints (Tapir)
108+
Define endpoints in `Endpoints. scala` with full type safety
109+
- Use `@accessible` macro for controller traits
110+
- Bind public endpoints: `bindEndpoint(endpoint, handler)`
111+
- Bind authenticated endpoints: `bindEndpoint(authController)(endpoint, handler)`
112+
- Add `. noCache` to prevent caching on real-time data
113+
- Read endpoints (GET) are typically public
114+
- Write endpoints (POST, PUT, DELETE) typically require authentication via API key
115+
116+
### Controllers Pattern
117+
```scala
118+
@accessible
119+
trait XController {
120+
def method(params): IO[ErrorResponse, Result]
121+
}
122+
123+
class XControllerImpl(dependencies) extends XController {
124+
def method(params): IO[ErrorResponse, Result] =
125+
// implementation with error handling
126+
}
127+
128+
object XControllerImpl {
129+
val layer: TaskLayer[XController] = ZLayer { /* ... */ }
130+
}
131+
```
132+
133+
### Checker Architecture
134+
The checker system uses a polymorphic design:
135+
- **Base trait**: `Checker` defines the core interface:
136+
```scala
137+
trait Checker {
138+
def checkRawStatus(action: StatusCheckAction): UIO[RawStatus]
139+
}
140+
```
141+
- **Specialized traits**: Each checker type has its own trait (e.g., `HttpGetRequestWithMessageChecker`, `AwsRdsChecker`, `AwsEmrChecker`)
142+
- **Implementations**: Concrete implementations for each specialized trait (e.g., `HttpGetRequestWithMessageCheckerImpl`)
143+
- **Polymorphic dispatcher**: `PolymorphicChecker` implements the base `Checker` trait and delegates to specialized checkers based on the `StatusCheckAction` subtype
144+
- **Supported checkers**:
145+
- HTTP-based: `HttpGetRequestStatusCodeOnly`, `HttpGetRequestWithMessage`, `HttpGetRequestWithJsonStatus`
146+
- AWS-based: `AwsRds`, `AwsRdsCluster`, `AwsEmr`, `AwsEc2AmiCompliance`
147+
- Special: `FixedStatus`, `TemporaryFixedStatus`, `Composition`
148+
149+
### Database Operations
150+
- Repository layer returns `IO[DatabaseError, Result]`
151+
- Controllers map `DatabaseError` to `ErrorResponse`
152+
- Use DynamoDB as primary persistence
153+
154+
## Testing Guidelines
155+
156+
### Scala Tests
157+
- Unit tests: `sbt test` - should require no external dependencies
158+
- Integration tests: Custom SBT commands (`testDynamo`, `testSMTP`, `testMSTeams`)
159+
- Use ZIO Test framework with `suite` and `test` functions
160+
- Mock external dependencies for unit tests
161+
- Use `ConfigProviderSpec` for test configurations
162+
- Test aspects: Use `@@ TestAspect. sequential` for tests that must run sequentially
163+
164+
### TypeScript Tests
165+
- Unit tests: `npm run test` (Jest via `jest.config.ts`)
166+
- E2E tests: `npm run e2e` (Cypress via `cypress.json`)
167+
- Test coverage: `npm run test:coverage`
168+
169+
## Configuration
170+
- Main config: `config. conf` (HOCON format)
171+
- Environment-specific configurations for different deployments
172+
- AWS credentials required (can be mocked for non-AWS environments)
173+
- DynamoDB endpoint configurable for local development
174+
- Configuration uses ZIO Config with magnolia derivation: `deriveConfig[T]. nested("path", "to", "config")`
175+
176+
## Build and Assembly
177+
- Backend: `sbt assembly` creates fat JAR in `target/scala-2.13/`
178+
- Frontend: `npm run build` in `ui/` directory
179+
- Version source of truth: `VERSION` file at root
180+
- Version sync: Frontend runs `npm run sync-version` (via `syncVersion.js`) to sync with VERSION file
181+
182+
## Dependency Management
183+
184+
### Scala Dependencies
185+
- Define dependencies in `project/Dependencies.scala`
186+
- Version constants in `Dependencies. Versions` object
187+
- Common dependencies in `Dependencies.commonDependencies` sequence
188+
- Referenced in `build.sbt`
189+
190+
### Frontend Dependencies
191+
- Add npm dependencies in `ui/package.json`
192+
- Major dependencies: Angular 19, PrimeNG, CPS UI Kit, RxJS
193+
194+
## API Documentation
195+
- Swagger UI available at `GET /docs`
196+
- Endpoints follow pattern: `/api/v1/{resource}`
197+
- Use typed requests/responses with Circe JSON codec
198+
199+
## Notifications
200+
- Email templates support variable substitution: `{{ SERVICE_NAME }}`, `{{ STATUS }}`, `{{ STATUS_COLOR }}`, etc.
201+
- MS Teams webhook integration
202+
- Notification logic in `notification/` package (templates in `src/main/resources/notifications/`)
203+
- Polymorphic design: `PolymorphicNotificationActioner` delegates to specialized actioners
204+
- Notification deciders: Duration-based logic to prevent notification spam
205+
206+
## Docker
207+
- Backend Dockerfile for service
208+
- UI.Dockerfile for frontend
209+
- docker-compose.yml for local DynamoDB setup
210+
- Follow comments in Dockerfiles for build/run instructions
211+
212+
## Release Management
213+
- Semver versioning in VERSION file (keep the file in sync with Git tags/CI release pipelines to avoid mismatches)
214+
- Snapshot builds: `X.Y.Z-SNAPSHOT`
215+
- Release builds: `X.Y.Z` (no suffix)
216+
- DEV deployment: automatic on merge to master
217+
- PROD deployment: manual trigger after release
218+
219+
## When Writing Code
220+
221+
### For Backend Changes
222+
1. Start with the model/domain types
223+
2. Add repository methods if database access needed
224+
3. Implement controller logic with proper error handling
225+
4. Define Tapir endpoints with all error cases
226+
5. Wire up in `RoutesImpl`
227+
6. Add tests covering happy path and error cases
228+
7. Update API documentation if endpoints change
229+
230+
### For Frontend Changes
231+
1. Create/modify Angular components
232+
2. Update services for API communication
233+
3. Use CPS UI Kit and PrimeNG components
234+
4. Add unit tests (Jest) and/or E2E tests (Cypress)
235+
5. Ensure responsive design
236+
6. Follow Angular reactive patterns with RxJS
237+
238+
### For Health Checkers
239+
1. Define a specialized trait in `checker/` package extending the checker pattern:
240+
```scala
241+
@accessible
242+
trait XChecker {
243+
def checkRawStatus(action: StatusCheckAction. X): UIO[RawStatus]
244+
}
245+
```
246+
2. Implement the trait in `XCheckerImpl` class
247+
3. Define a ZIO layer in the companion object
248+
4. Add the checker to `PolymorphicChecker` to handle the new action type
249+
5. Support configuration from HOCON if needed
250+
6. Return typed status results: `RawStatus. Green`, `RawStatus.Amber`, or `RawStatus.Red`
251+
7. Use `intermittent` flag for transient failures
252+
8. Add integration tests
253+
9. Document in wiki under "Supported checkers"
254+
255+
## Common Commands
256+
```bash
257+
# Backend
258+
sbt clean test # Clean + unit tests
259+
sbt compile # Compile
260+
sbt assembly # Build fat JAR
261+
sbt jacoco # Code coverage
262+
263+
# Frontend
264+
npm run start # Dev server
265+
npm run build # Production build
266+
npm run test # Unit tests (Jest)
267+
npm run e2e # E2E tests (Cypress)
268+
npm run lint # Lint & format check
269+
npm run lint:fix # Auto-fix linting issues
270+
npm run sync-version # Sync VERSION file to package.json
271+
```
272+
273+
## AWS Integration
274+
- AWS SDK used for: DynamoDB, RDS, RDS Clusters, EMR, EC2
275+
- ZIO-AWS library provides typed AWS integrations
276+
- Region configuration per service check
277+
- Endpoint override available for local testing
278+
279+
## Additional Resources
280+
- [Wiki - REST API](https://github.com/AbsaOSS/StatusBoard/wiki/REST-API)
281+
- [Wiki - Architecture](https://github.com/AbsaOSS/StatusBoard/wiki/Architecture)
282+
- [Wiki - Supported Checkers](https://github.com/AbsaOSS/StatusBoard/wiki/Supported-checkers)

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @benedeki @lsulak @Zejnilovic @salamonpavel @petr-pokorny-absa @oto-macenauer-absa @tmikula-dev
1+
* @lsulak @Zejnilovic @salamonpavel @petr-pokorny-absa @oto-macenauer-absa @tmikula-dev

0 commit comments

Comments
 (0)