Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a545772
feat: implement TimePicker component for improved time selection in r…
Nov 14, 2025
fd43cba
Made fixes on comment and gatekeeper appliance access
Jan 9, 2026
05f4375
feat: add sanction management features including SanctionRecord model…
Mar 18, 2026
86934c2
Added gatekeeper priority
Mar 20, 2026
2cdacb7
Fixed bug: calendar card shift
Mar 20, 2026
0f42f30
Remove SANCTIONED status from ReservationStatus enum and related logi…
Mar 22, 2026
8ab6e2b
feat: add OpenedWeek model and enhance Settings with new attributes f…
Mar 22, 2026
1a8ce55
Merge origin/main and resolve conflicts
Mar 22, 2026
459f9c2
Add missing sonner dependency for frontend
Mar 22, 2026
0ab44ce
Refactor: remove ReservationConfig and SanctionTier models, along wit…
Mar 23, 2026
49c3f85
Build error fix
Mar 23, 2026
4d1a9d7
Merge remote-tracking branch 'origin/frontend_refactor' into feature/…
Mar 23, 2026
9052054
Enhance reservation management: include gatekeeper details in reserva…
Mar 23, 2026
e3a4587
Enhance reservation functionality: add optional gatekeeper ID to find…
Mar 23, 2026
d9855e9
ESLint fixes
Mar 24, 2026
81cff6f
Enhance sanction records functionality: add reservationId to sanction…
Mar 26, 2026
c620671
Added missing migration file and fixed ESLint errors/warnings
Mar 26, 2026
fe6a1c4
feat: enhance authorization and settings management
Jun 18, 2026
9e29f53
fix: address CodeRabbit/Copilot PR review findings
Jun 19, 2026
4d84061
fix: address CodeRabbit/Copilot PR review findings
Jun 19, 2026
8d59ac6
refactor: replace string literals with ReservationStatus enum in comm…
Jun 19, 2026
f9f9812
refactor: replace string literals with ReservationStatus enum in comm…
Jun 19, 2026
e8537ca
feat(auth): add leadership title check and role assignment for club m…
Aug 28, 2026
d64ce48
feat(auth): add leadership title check and role assignment for club m…
Aug 28, 2026
d68c64e
Merge remote-tracking branch 'origin/main' into feature/reservationad…
Oct 27, 2026
b25f1db
fix: harden reservation, admission and sanction rules; simplify frontend
Oct 27, 2026
708a83c
docs: update project docs, deploy notes and CI checks
Oct 27, 2026
cace54b
chore: revert generated documentation updates and add agent guidelines
Oct 27, 2026
f21f744
chore: reconcile remote history with equivalent local commits
Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
env: {
node: true,
},
ignorePatterns: ['.eslintrc.js', '.prettierrc.js'],
ignorePatterns: ['.eslintrc.js', '.prettierrc.js', 'apps/frontend/next-env.d.ts'],
rules: {
'prettier/prettier': 'error',
'simple-import-sort/imports': 'error',
Expand Down
31 changes: 28 additions & 3 deletions .github/workflows/analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22

- name: Install dependencies
run: yarn install
Expand All @@ -39,7 +39,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22

- name: Install dependencies
run: yarn install
Expand All @@ -53,17 +53,42 @@ jobs:
needs:
- lint-check
- format-check
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: mmmk
POSTGRES_PASSWORD: mmmk
POSTGRES_DB: mmmk
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 10
env:
DATABASE_URL: postgresql://mmmk:mmmk@localhost:5432/mmmk
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22

- name: Install dependencies
run: yarn install

- name: Build
run: cd apps/backend && yarn prisma generate && yarn build

- name: Type-check and build frontend
run: cd apps/frontend && npx tsc --noEmit && yarn build
env:
NEXT_PUBLIC_API_URL: http://localhost:3030

- name: Apply migrations to an empty database
run: cd apps/backend && yarn prisma migrate deploy

- name: Test
run: cd apps/backend && yarn test:backend
env:
MMMK_RUN_DATABASE_TESTS: '1'
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ yarn-error.log*
.DS_Store
.env
.amazonq

qa-*
copilot.*

# Logs
*.log
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
.idea
dist
.next
.next
next-env.d.ts
68 changes: 68 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# AGENTS.md

This repository contains a full-stack application using NestJS 11 + Prisma 6 (backend) and Next.js 16 / React 19 (frontend) in a Yarn monorepo (Node 22). Product rules, structure and conventions: `project_info/`.

## Build/Lint/Test Commands

### Development

- **Backend:** `yarn start:backend` (runs `apps/backend` in dev mode)
- **Frontend:** `yarn start:frontend` (runs `apps/frontend` in dev mode)

### Build

- **Backend:** `yarn build:backend`
- **Frontend:** `yarn build:frontend`

### Linting & Formatting

- **Lint:** `yarn lint`
- **Lint Fix:** `yarn lint:fix`
- **Format:** `yarn format`
- **Format Check:** `yarn format:check`

### Testing

- **Backend:** `cd apps/backend && yarn test:backend` (Jest 30)
- **DB integration tests:** opt-in with `MMMK_RUN_DATABASE_TESTS=1` and `DATABASE_URL`; CI runs them on Postgres (`.github/workflows/analysis.yml`)
- **Frontend:** no tests; type-check with `cd apps/frontend && npx tsc --noEmit`

---

## Code Style & Guidelines

### TypeScript

- Use TypeScript for all new code.
- Strict typing is encouraged.

### Backend (NestJS)

- Follow NestJS conventions: controllers, services, modules, DTOs, entities.
- Use dependency injection for services.
- Validate incoming data using `class-validator` and `class-transformer`.
- Structure: `apps/backend/src/<feature>/`; shared helpers in `src/utils/`.
- Prisma errors are mapped globally (`main.ts`); don't wrap calls in try/catch just to map `P2025`.
- Env vars: `apps/backend/.env.example`. Schema changes need a migration.

### Frontend (Next.js)

- Follow Next.js App Router conventions. Route protection is `src/proxy.ts` (Next 16 replaced `middleware.ts`) plus the `withAuth` HOCs.
- Structure: `apps/frontend/src/app/` for routes, `apps/frontend/src/components/` for reusable UI.
- Styling: Tailwind CSS.
- Components: Use shadcn/ui components where applicable.

### General

- **Imports:** Use absolute imports if configured, otherwise be consistent with the project's relative import style.
- **Naming Conventions:**
- Use camelCase for functions, variables, and properties.
- Use PascalCase for classes, components, and interfaces/types.
- **Error Handling:**
- Use meaningful error messages; user-facing messages are Hungarian.
- Leverage NestJS Exception Filters in the backend.
- **Formatting:** Prettier is used. Ensure `yarn format:check` passes before committing.

---

_This file serves as the primary guideline for autonomous agents working in this repository._
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,3 @@ yarn build:backend
```

## Happy Coding!



34 changes: 34 additions & 0 deletions apps/backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# PostgreSQL kapcsolat (Prisma)
DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/mmmk"

# AuthSCH OAuth kliens
AUTHSCH_CLIENT_ID="your-authsch-client-id"
AUTHSCH_CLIENT_SECRET="your-authsch-client-secret"

# JWT aláíró kulcs (hosszú, véletlen string)
JWT_SECRET="change-me"

# Frontend origin (CORS) és a bejelentkezés utáni visszairányítás címe
FRONTEND_URL="http://localhost:3000"
FRONTEND_CALLBACK_URL="http://localhost:3000/callback"

# A backend portja (alapértelmezés: 3030); a docker-compose a BACKEND_PORT-ot használja a port-mappinghez
PORT=3030
BACKEND_PORT=3030

# PEK szinkron: a kör neve és a titulusok
PEK_GROUP_NAME="Muzsika mívelő mérnökök klubja"
PEK_MEMBER_TITLE="tag"
PEK_NEWBIE_TITLE="újonc"
PEK_GATEKEEPER_TITLE="beengedő"
# Opcionális: ez a titulus is beengedő jogot ad
PEK_ROOM_MANAGER_TITLE=""
# Opcionális: admin jogot adó titulusok vesszővel elválasztva (alapértelmezés: körvezető,teremmester,ac)
# PEK_LEADERSHIP_TITLES="körvezető,teremmester,ac"

# Szerveroldali e-mail értesítések (kir-mail)
KIR_MAIL_URL="https://kir-mail.example.com"
KIR_MAIL_TOKEN="your-kir-mail-token"

# Csak tesztekhez: 1 esetén lefutnak az adatbázisos integrációs tesztek
# MMMK_RUN_DATABASE_TESTS=1
14 changes: 14 additions & 0 deletions apps/backend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Same club timezone as main.ts, so day/week boundaries in tests match the running server.
process.env.TZ = 'Europe/Budapest';

module.exports = {
moduleFileExtensions: ['js', 'json', 'ts'],
rootDir: 'src',
testRegex: '.*\\.spec\\.ts$',
transform: {
'^.+\\.(t|j)s$': 'ts-jest',
},
collectCoverageFrom: ['**/*.{ts,js}'],
coverageDirectory: '../coverage',
testEnvironment: 'node',
};
32 changes: 19 additions & 13 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,24 @@
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main"
"start:prod": "node dist/main",
"test:backend": "jest"
},
"dependencies": {
"@kir-dev/passport-authsch": "^2.2.2",
"@nestjs/common": "^10.4.16",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.1.18",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.8",
"@nestjs/swagger": "^7.3.1",
"@kir-dev/passport-authsch": "^2.2.5",
"@nestjs/common": "^11.2.8",
"@nestjs/config": "^4.0.4",
"@nestjs/core": "^11.2.8",
"@nestjs/jwt": "^11.0.2",
"@nestjs/mapped-types": "^2.1.1",
"@nestjs/passport": "^11.0.5",
"@nestjs/platform-express": "^11.2.8",
"@nestjs/swagger": "^11.4.7",
"@prisma/client": "6.3.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cors": "^2.8.5",
"nestjs-prisma": "^0.23.0",
"nestjs-prisma": "^0.27.0",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"prisma": "6.3.1",
Expand All @@ -35,13 +37,17 @@
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@types/express": "^4.17.21",
"@nestjs/cli": "^11.0.24",
"@nestjs/schematics": "^11.1.0",
"@nestjs/testing": "^11.2.8",
"@types/express": "^5.0.6",
"@types/jest": "^30.0.0",
"@types/node": "^20.12.7",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"jest": "^30.3.0",
"source-map-support": "^0.5.21",
"ts-jest": "^29.4.6",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"tsconfig-paths": "4.2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- AlterEnum
ALTER TYPE "ReservationStatus" ADD VALUE 'SANCTIONED';

-- AlterTable
ALTER TABLE "Period" ADD COLUMN "isOpen" BOOLEAN NOT NULL DEFAULT false;

-- AlterTable
ALTER TABLE "User" ADD COLUMN "sanctionPoints" INTEGER NOT NULL DEFAULT 0;

-- CreateTable
CREATE TABLE "Settings" (
"id" SERIAL NOT NULL,
"maxHoursPerWeek" DOUBLE PRECISION NOT NULL DEFAULT 8.0,
"maxHoursPerDay" DOUBLE PRECISION NOT NULL DEFAULT 4.0,
"minReservationMinutes" INTEGER NOT NULL DEFAULT 30,
"maxReservationMinutes" INTEGER NOT NULL DEFAULT 180,
"sanctionHourPenaltyPerPoint" DOUBLE PRECISION NOT NULL DEFAULT 1.0,

CONSTRAINT "Settings_pkey" PRIMARY KEY ("id")
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Reservation" ADD COLUMN "needToBeLetIn" BOOLEAN NOT NULL DEFAULT false;
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Warnings:

- You are about to drop the column `sanctionPoints` on the `User` table. All the data in the column will be lost.

*/
-- AlterTable
ALTER TABLE "User" DROP COLUMN "sanctionPoints";

-- CreateTable
CREATE TABLE "SanctionRecord" (
"id" SERIAL NOT NULL,
"userId" INTEGER,
"bandId" INTEGER,
"points" INTEGER NOT NULL,
"reason" TEXT NOT NULL,
"awardedBy" INTEGER NOT NULL,
"awardedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "SanctionRecord_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "SanctionRecord" ADD CONSTRAINT "SanctionRecord_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "SanctionRecord" ADD CONSTRAINT "SanctionRecord_bandId_fkey" FOREIGN KEY ("bandId") REFERENCES "Band"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "SanctionRecord" ADD CONSTRAINT "SanctionRecord_awardedBy_fkey" FOREIGN KEY ("awardedBy") REFERENCES "ClubMembership"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "GateKeeperPriority" AS ENUM ('PRIMARY', 'SECONDARY');

-- AlterTable
ALTER TABLE "Reservation" ADD COLUMN "gateKeeperPriority" "GateKeeperPriority";
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
Warnings:

- The values [SANCTIONED] on the enum `ReservationStatus` will be removed. If these variants are still used in the database, this will fail.

*/
-- AlterEnum
BEGIN;
CREATE TYPE "ReservationStatus_new" AS ENUM ('NORMAL', 'OVERTIME', 'ADMINMADE');
ALTER TABLE "Reservation" ALTER COLUMN "status" TYPE "ReservationStatus_new" USING ("status"::text::"ReservationStatus_new");
ALTER TYPE "ReservationStatus" RENAME TO "ReservationStatus_old";
ALTER TYPE "ReservationStatus_new" RENAME TO "ReservationStatus";
DROP TYPE "ReservationStatus_old";
COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- AlterTable
ALTER TABLE "Settings" ADD COLUMN "banSanctionPointThreshold" INTEGER NOT NULL DEFAULT 5,
ADD COLUMN "maxTotalHoursPerWeek" DOUBLE PRECISION NOT NULL DEFAULT 12.0,
ADD COLUMN "sanctionTotalHourPenaltyPerPoint" DOUBLE PRECISION NOT NULL DEFAULT 2.0;

-- CreateTable
CREATE TABLE "OpenedWeek" (
"id" SERIAL NOT NULL,
"monday" TIMESTAMP(3) NOT NULL,
"isOpen" BOOLEAN NOT NULL DEFAULT false,

CONSTRAINT "OpenedWeek_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "OpenedWeek_monday_key" ON "OpenedWeek"("monday");
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
Warnings:

- You are about to drop the `ReservationConfig` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `SanctionTier` table. If the table is not empty, all the data it contains will be lost.

*/
-- DropForeignKey
ALTER TABLE "SanctionTier" DROP CONSTRAINT "SanctionTier_configId_fkey";

-- DropTable
DROP TABLE "ReservationConfig";

-- DropTable
DROP TABLE "SanctionTier";
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "SanctionRecord" ADD COLUMN "reservationId" INTEGER;

-- AddForeignKey
ALTER TABLE "SanctionRecord" ADD CONSTRAINT "SanctionRecord_reservationId_fkey" FOREIGN KEY ("reservationId") REFERENCES "Reservation"("id") ON DELETE SET NULL ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ALTER TABLE "Settings" ALTER COLUMN "maxHoursPerWeek" SET DEFAULT 6.0;
ALTER TABLE "Settings" ALTER COLUMN "maxHoursPerDay" SET DEFAULT 3.0;

UPDATE "Settings"
SET "maxHoursPerWeek" = 6.0
WHERE "maxHoursPerWeek" = 8.0;

UPDATE "Settings"
SET "maxHoursPerDay" = 3.0
WHERE "maxHoursPerDay" = 4.0;
Loading
Loading