Update readme's, branches and actions
Build and Push Docker Images / detect-changes (push) Successful in 10s
Build and Push Docker Images / build-auth-api (push) Successful in 58s
Build and Push Docker Images / build-employee-api (push) Successful in 58s
Build and Push Docker Images / build-transit-api (push) Successful in 59s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m8s
Build and Push Docker Images / build-admin-ui (push) Successful in 1m14s
Build and Push Docker Images / deploy-test-node (push) Successful in 5s

This commit is contained in:
Sven laptop
2026-09-17 12:04:44 +02:00
parent fdbdb98b21
commit 9d1a37e248
158 changed files with 428 additions and 176 deletions
+204 -43
View File
@@ -3,43 +3,63 @@ name: Build and Push Docker Images
on:
push:
branches:
- main
- develop
paths:
- "auth_api/**"
- "employee_api/**"
- "transit_api/**"
- "error_log_api/**"
- "admin_ui/**"
- "docker-compose.yml"
- ".gitea/workflows/docker-build.yml"
- dev
- auth-api
- employee-api
- transit-api
- error-log-api
- admin-ui
pull_request:
branches:
- main
- develop
- dev
env:
REGISTRY: gitea.testinstance.nl
IMAGE_NAMESPACE: sven/the-transit-project
jobs:
build-and-push:
detect-changes:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: auth_api
context: ./auth_api
- name: employee_api
context: ./employee_api
- name: transit_api
context: ./transit_api
- name: error_log_api
context: ./error_log_api
- name: admin_ui
context: ./admin_ui
outputs:
auth_api: ${{ steps.filter.outputs.auth_api }}
employee_api: ${{ steps.filter.outputs.employee_api }}
transit_api: ${{ steps.filter.outputs.transit_api }}
error_log_api: ${{ steps.filter.outputs.error_log_api }}
admin_ui: ${{ steps.filter.outputs.admin_ui }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Detect changed paths
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
auth_api:
- 'auth_api/**'
- 'docker-compose.yml'
- '.gitea/workflows/docker-build.yml'
employee_api:
- 'employee_api/**'
- 'docker-compose.yml'
- '.gitea/workflows/docker-build.yml'
transit_api:
- 'transit_api/**'
- 'docker-compose.yml'
- '.gitea/workflows/docker-build.yml'
error_log_api:
- 'error_log_api/**'
- 'docker-compose.yml'
- '.gitea/workflows/docker-build.yml'
admin_ui:
- 'admin_ui/**'
- 'docker-compose.yml'
- '.gitea/workflows/docker-build.yml'
build-auth-api:
needs: detect-changes
if: ${{ (gitea.ref_name == 'auth-api' || gitea.ref_name == 'dev') && needs.detect-changes.outputs.auth_api == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -58,29 +78,170 @@ jobs:
id: tags
shell: bash
run: |
image_base="${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ matrix.name }}"
image_tags="${image_base}:${{ gitea.sha }}"
image_base="${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/auth_api"
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.ref_name }}" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.sha }}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
if [[ "${{ gitea.event_name }}" == "push" && "${{ gitea.ref_name }}" == "main" ]]; then
image_tags+=$'\n'"${image_base}:latest"
fi
{
echo 'tags<<EOF'
echo "$image_tags"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Build and push
- name: Build and push auth_api
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
context: ./auth_api
push: ${{ gitea.event_name == 'push' }}
tags: ${{ steps.tags.outputs.tags }}
build-employee-api:
needs: detect-changes
if: ${{ (gitea.ref_name == 'employee-api' || gitea.ref_name == 'dev') && needs.detect-changes.outputs.employee_api == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set image tags
id: tags
shell: bash
run: |
image_base="${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/employee_api"
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.ref_name }}" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.sha }}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Build and push employee_api
uses: docker/build-push-action@v6
with:
context: ./employee_api
push: ${{ gitea.event_name == 'push' }}
tags: ${{ steps.tags.outputs.tags }}
build-transit-api:
needs: detect-changes
if: ${{ (gitea.ref_name == 'transit-api' || gitea.ref_name == 'dev') && needs.detect-changes.outputs.transit_api == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set image tags
id: tags
shell: bash
run: |
image_base="${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/transit_api"
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.ref_name }}" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.sha }}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Build and push transit_api
uses: docker/build-push-action@v6
with:
context: ./transit_api
push: ${{ gitea.event_name == 'push' }}
tags: ${{ steps.tags.outputs.tags }}
build-error-log-api:
needs: detect-changes
if: ${{ (gitea.ref_name == 'error-log-api' || gitea.ref_name == 'dev') && needs.detect-changes.outputs.error_log_api == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set image tags
id: tags
shell: bash
run: |
image_base="${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/error_log_api"
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.ref_name }}" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.sha }}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Build and push error_log_api
uses: docker/build-push-action@v6
with:
context: ./error_log_api
push: ${{ gitea.event_name == 'push' }}
tags: ${{ steps.tags.outputs.tags }}
build-admin-ui:
needs: detect-changes
if: ${{ (gitea.ref_name == 'admin-ui' || gitea.ref_name == 'dev') && needs.detect-changes.outputs.admin_ui == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set image tags
id: tags
shell: bash
run: |
image_base="${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/admin_ui"
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.ref_name }}" >> "$GITHUB_OUTPUT"
echo "${image_base}:${{ gitea.sha }}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Build and push admin_ui
uses: docker/build-push-action@v6
with:
context: ./admin_ui
push: ${{ gitea.event_name == 'push' }}
tags: ${{ steps.tags.outputs.tags }}
deploy-test-node:
needs: build-and-push
if: ${{ gitea.event_name == 'push' && gitea.ref_name == 'main' }}
needs:
[
detect-changes,
build-auth-api,
build-employee-api,
build-transit-api,
build-error-log-api,
build-admin-ui,
]
if: ${{ gitea.event_name == 'push' && gitea.ref_name == 'dev' }}
runs-on: ubuntu-latest
steps:
+60 -12
View File
@@ -1,13 +1,50 @@
# Environment and secrets
.env
/*.env
transit_api/.env
error_log_api/.env
.env.*
!.env.example
**/.env
**/.env.*
!**/.env.example
# Local build / node_modules
# Node.js
node_modules/
admin_ui/node_modules/
admin_ui/dist/
coverage/
dist/
build/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Sensitive docs to keep private
# Flutter / Dart
**/.dart_tool/
**/.pub-cache/
**/.pub/
**/build/
**/.flutter-plugins
**/.flutter-plugins-dependencies
# Database and local artifacts
*.sqlite
*.sqlite3
*.db
dump.sql
# Certificates and keys
*.pem
*.key
*.crt
*.p12
# OS/editor files
.DS_Store
.vscode/
.idea/
# Sensitive project docs
ADMIN_DEPLOYMENT_SUMMARY.md
CI_CD_PORTAINER_GUIDE.md
DEPLOYMENT.md
@@ -17,7 +54,7 @@ INTERNAL_*.md
SETUP_*.md
DEPLOY_*.md
# Custom instruction files (private)
# Private instructions and tooling files
.instructions.md
.prompt.md
.agent.md
@@ -25,15 +62,26 @@ SKILL.md
copilot-instructions.md
AGENTS.md
# Private scripts
# Local/private scripts
scripts/private/
scripts/*.local.*
scripts/.env
# Private timetable note
# Project-specific private notes
transit_api/LOCAL_BUS_TIMETABLE_README.md
# Runtime files
*.log
*.sqlite3
.DS_Store
# Deprecated app backups and legacy artifacts
deprecated/build/
deprecated/.dart_tool/
deprecated/.pub-cache/
deprecated/.idea/
deprecated/.vscode/
# Runtime logs
auth_api.log
transit_api.log
error_log_api.log
# Temporary files
tmp/
temp/
+15 -4
View File
@@ -1,11 +1,13 @@
# Transit Project
Dit repository bevat een suite van drie Node.js microservices (APIs) en bijbehorende tooling:
Dit repository bevat een suite van Node.js microservices, een admin webapp en een legacy desktop client die momenteel als deprecated wordt bewaard.
- `auth_api` — Authenticatie en token-uitgifte (standaard port 5000)
- `employee_api` — Employee onboarding / management (standaard port 4000)
- `transit_api` — Transit/schedule endpoints (standaard port 5001)
- `error_log_api` — Centrale foutlogging en viewer (standaard port 5003)
- `admin_ui` — React + Vite beheerinterface
- `deprecated/` — legacy Flutter bus terminal, retained for reference while moving the client to a Windows XP-era build path
Er is ook een GitHub Actions workflow aanwezig die Docker images bouwt en pusht naar GitHub Container Registry (GHCR).
@@ -23,6 +25,7 @@ Belangrijk: deze README bevat geen wachtwoorden of andere gevoelige gegevens. Sl
- Guidelines for adding new private files
**Private files are excluded** (not in git/docker):
- `GETTING_STARTED.md` - Internal setup guide
- `ADMIN_DEPLOYMENT_SUMMARY.md` - Deployment status
- `CI_CD_PORTAINER_GUIDE.md` - Infrastructure docs
@@ -125,6 +128,7 @@ Tip: tijdens development kun je één Postgres instance gebruiken en schema/roll
Deze repository bevat `docker-compose.yml` die images vanuit GHCR trekt. De compose is aangepast om een externe Postgres te gebruiken.
Voordat je start:
- Zorg dat je `.env` met database credentials en `JWT_SECRET` klaar staat op de server.
- Zorg dat de host waar je compose draait netwerk-connectiviteit heeft naar de Postgres host.
@@ -162,10 +166,12 @@ Het project bevat een workflow in `.github/workflows/docker-build.yml` die bij p
- Genereert tags (`latest`, branch/sha, semver als aanwezig)
Om GHCR te gebruiken op je server:
1. Maak een Personal Access Token (PAT) met `read:packages` (en `write:packages` indien je zelf ook wilt pushen).
2. Login op de server: `docker login ghcr.io` (gebruik PAT als wachtwoord).
Image naam voorbeeld:
```
ghcr.io/<github-username>/<repo>/auth_api:latest
```
@@ -191,6 +197,7 @@ docker logs -f auth_api
```
Problemen met DB-verbinding:
- Controleer netwerkconnectiviteit naar `POSTGRES_HOST`
- Controleer users/permissions in Postgres
- Controleer dat de juiste schema (zoals `workers`) bestaat als de queries die verwachten
@@ -221,6 +228,7 @@ docker login ghcr.io
## Migraties & Database schema
Database schema en migraties zitten niet in deze repository. Zorg dat je:
- de juiste schema's (`workers`, `routes`, etc.) aanmaakt
- gebruikers en rechten configureert voor de verschillende services
@@ -340,20 +348,23 @@ docker-compose up admin_ui
The Transit API exposes public (unauthenticated) schedule endpoints:
**Endpoints:**
- `GET /schedules?date=YYYY-MM-DD&lineId=ID` — Get schedules for a date/line
- `GET /schedules/:scheduleId` — Get schedule details
- `GET /schedules/:scheduleId/stops` — Get stops on a schedule's line
**Example:**
```bash
curl http://localhost:5001/schedules?date=2026-05-06
```
**TimetableViewer Component:**
```jsx
import TimetableViewer from './components/TimetableViewer'
<TimetableViewer apiBaseUrl="http://api.transit.local:5001" />
```jsx
import TimetableViewer from "./components/TimetableViewer";
<TimetableViewer apiBaseUrl="http://api.transit.local:5001" />;
```
### Schedule Maker Documentation
+17 -5
View File
@@ -5,15 +5,17 @@ This document explains which files are kept private and why.
## Files Excluded from Git & Docker
### Deployment Documentation (Private)
- `ADMIN_DEPLOYMENT_SUMMARY.md` - Internal deployment status and setup details
- `CI_CD_PORTAINER_GUIDE.md` - Private CI/CD and Portainer configuration
- `DEPLOYMENT.md` - Deployment procedures and configuration guidance
- `GETTING_STARTED.md` - Internal setup instructions
- `INTERNAL_*.md` - Any file prefixed with INTERNAL_ (pattern-based exclusion)
- `SETUP_*.md` - Any file prefixed with SETUP_ (pattern-based exclusion)
- `DEPLOY_*.md` - Any file prefixed with DEPLOY_ (pattern-based exclusion)
- `INTERNAL_*.md` - Any file prefixed with INTERNAL\_ (pattern-based exclusion)
- `SETUP_*.md` - Any file prefixed with SETUP\_ (pattern-based exclusion)
- `DEPLOY_*.md` - Any file prefixed with DEPLOY\_ (pattern-based exclusion)
### Custom Instruction Files (Private)
- `.instructions.md` - GitHub Copilot custom instructions
- `.prompt.md` - Custom prompt templates
- `.agent.md` - Custom agent definitions
@@ -22,26 +24,30 @@ This document explains which files are kept private and why.
- `AGENTS.md` - Agent configuration
These are kept private to prevent exposure of:
- Development workflow details
- Copilot customization strategies
- Internal coding guidelines and preferences
- Prompt engineering techniques
### Private Scripts
- `scripts/private/` - Directory for private deployment scripts
- `scripts/*.local.*` - Local-specific script configurations
## Files Included in Public Repo
### Public Documentation
- `README.md` - Main project documentation
- `DOCKER_README.md` - Docker usage documentation
- `admin_ui/README.md` - Admin UI documentation
- `admin_ui/SCHEDULE_API.md` - Public API documentation
- `transit_api/README.md` - API documentation
- `bus_terminal/README.md` - Flutter app documentation
- `deprecated/README.md` - Legacy Flutter bus terminal documentation kept for historical reference
### Configuration
- `.env.example` - Environment variable template (no secrets)
- `.gitignore` - Git exclusion rules
- `.dockerignore` - Docker build exclusion rules
@@ -49,13 +55,15 @@ These are kept private to prevent exposure of:
- `Dockerfile` files - Container definitions
### Code & Configuration
- All source code in `auth_api/`, `transit_api/`, `employee_api/`, `admin_ui/`, `bus_terminal/`
- All source code in `auth_api/`, `transit_api/`, `employee_api/`, `admin_ui/`, and the legacy `deprecated/` app
- `package.json` files (no secrets, only dependencies)
- GitHub Actions workflows in `.github/workflows/`
## Environment Variables - NEVER Commit
Always keep the following OUT of git:
- `.env` - Local environment variables (in `.gitignore`)
- Database credentials
- JWT secrets
@@ -67,6 +75,7 @@ Use `.env.example` as a template and create local `.env` files for development.
## Docker Build Security
All `.dockerignore` files (root and per-service) ensure that:
1. Sensitive documentation never enters Docker images
2. Private scripts and configs are excluded from builds
3. Only necessary source code and dependencies are included
@@ -75,6 +84,7 @@ All `.dockerignore` files (root and per-service) ensure that:
## GitHub Actions Security
The CI/CD workflow in `.github/workflows/docker-build.yml`:
- Only builds from specific service directories (auth_api, transit_api, etc.)
- Respects `.dockerignore` rules
- Uses GitHub secrets for credentials (never hardcoded)
@@ -93,12 +103,14 @@ The CI/CD workflow in `.github/workflows/docker-build.yml`:
To keep new private files out of the repo and Docker:
1. Add pattern to `.gitignore`:
```
MYFILE_*.md
new_private_thing.*
```
2. Add pattern to `.dockerignore` (root and per-service):
```
/MYFILE_*.md
/new_private_thing.*
-48
View File
@@ -1,48 +0,0 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
#github
.github/
-3
View File
@@ -1,3 +0,0 @@
# bus_terminal
A new Flutter project.
-35
View File
@@ -1,35 +0,0 @@
{
"name": "bus_terminal",
"short_name": "bus_terminal",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
+44
View File
@@ -0,0 +1,44 @@
# Flutter / Dart
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/
**/doc/api/
**/ios/Flutter/.last_build_id
# IDE / editor
.idea/
.vscode/
*.iml
*.ipr
*.iws
# OS files
.DS_Store
*.swp
# Environment and secrets
.env
.env.*
!.env.example
# Generated and platform artifacts
android/key.properties
android/app/debug
android/app/profile
android/app/release
# Logs and temp files
*.log
*.tmp
# Symbolication / obfuscation
*.symbols
*.map.json
# Legacy migration note
legacy_windows_xp_plan.md
+24
View File
@@ -0,0 +1,24 @@
# Deprecated: Legacy Bus Terminal
This Flutter application is retained as a legacy reference implementation while the transit client moves away from the Android-era setup toward a Windows XP-era compatibility target.
## Status
- Deprecated: yes
- Legacy platform target: Android-era Flutter app
- Planned migration target: Windows XP-era desktop workflow
- Kept in repo: for archival and reference during transition
## Notes
This project is not the active client for current operations. It remains available so the older UI, navigation logic, and service integration can be reviewed while the new target is prepared.
## Local development
```bash
cd deprecated
flutter pub get
flutter run
```
Use the appropriate device/desktop target when testing the legacy implementation.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 544 B

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 721 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 68 B

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 68 B

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 68 B

@@ -15,7 +15,7 @@ void main() {
FlutterError.onError = (details) {
FlutterError.presentError(details);
void report() => ErrorLogService.report(
service: 'bus_terminal',
service: 'deprecated',
partOfService: 'FlutterError.onError',
error: details.exceptionAsString(),
);
@@ -26,23 +26,26 @@ void main() {
PlatformDispatcher.instance.onError = (error, stack) {
// ignore: unawaited_futures
ErrorLogService.report(
service: 'bus_terminal',
service: 'deprecated',
partOfService: 'PlatformDispatcher.onError',
error: '$error\n$stack',
);
return true;
};
runZonedGuarded(() {
runZonedGuarded(
() {
runApp(const MainApp());
}, (error, stack) {
},
(error, stack) {
// ignore: unawaited_futures
ErrorLogService.report(
service: 'bus_terminal',
service: 'deprecated',
partOfService: 'runZonedGuarded',
error: '$error\n$stack',
);
});
},
);
}
class MainApp extends StatelessWidget {

Some files were not shown because too many files have changed in this diff Show More