Merge branch 'feature/going-to-monorepo' into develop
@@ -20,7 +20,10 @@
|
||||
"mcp__context7__resolve-library-id",
|
||||
"mcp__context7__get-library-docs",
|
||||
"mcp__serena__create_text_file",
|
||||
"Bash(curl:*)"
|
||||
"Bash(curl:*)",
|
||||
"Bash(git mv:*)",
|
||||
"Bash(rmdir:*)",
|
||||
"Bash(mkdir:*)"
|
||||
]
|
||||
},
|
||||
"enableAllProjectMcpServers": true,
|
||||
|
||||
6
.gitignore
vendored
@@ -1,14 +1,16 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
# next.js (in web-app workspace)
|
||||
web-app/.next/
|
||||
web-app/out/
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
|
||||
18
CHANGELOG.md
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- **Repository Structure**: Converted to multi-project monorepo
|
||||
- `web-app/` - Main Next.js application (formerly root directory)
|
||||
- `housekeeping/` - Database backup and maintenance scripts
|
||||
- **Docker Configuration**: Updated Dockerfile and docker-compose files for new directory structure
|
||||
- **Documentation**: Updated README.md and CLAUDE.md to reflect new structure
|
||||
|
||||
### Migration Notes
|
||||
- All application code moved to `web-app/` directory using `git mv` to preserve history
|
||||
- All database backup scripts moved to `housekeeping/` directory
|
||||
- Each project is self-contained with its own package.json and dependencies
|
||||
- Docker builds install dependencies from `web-app/` directory
|
||||
- Volume mounts in docker-compose updated to reference `web-app/etc/hosts/`
|
||||
- `.gitignore` updated to handle `node_modules` at any directory level
|
||||
- No workspace management - each project is completely independent
|
||||
|
||||
## [2.17.0] - 2025-12-21
|
||||
|
||||
### Changed
|
||||
|
||||
54
CLAUDE.md
@@ -2,20 +2,41 @@
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Repository Structure
|
||||
|
||||
This is a multi-project repository containing:
|
||||
- **web-app/**: Next.js 14 utility bills tracking application
|
||||
- **docker-stack/**: Docker Compose configurations and deployment scripts
|
||||
- **housekeeping/**: Database backup and maintenance scripts
|
||||
|
||||
Each project is self-contained with its own dependencies.
|
||||
|
||||
## Development Commands
|
||||
|
||||
- `npm run dev` - Start development server (Next.js)
|
||||
- `npm run build` - Build production version
|
||||
All commands should be run from within the respective project directory.
|
||||
|
||||
**Web App** (`cd web-app`):
|
||||
- `npm install` - Install dependencies
|
||||
- `npm run dev` - Start development server
|
||||
- `npm run build` - Build production version
|
||||
- `npm start` - Start production server
|
||||
- `npm run prettier` - Format code with Prettier
|
||||
- `npm run prettier:check` - Check code formatting
|
||||
- `npm run prettier` - Format code
|
||||
- `npm run seed` - Seed database with initial data
|
||||
|
||||
**Housekeeping** (`cd housekeeping`):
|
||||
- `./db-backup--standalone.sh` - Run standalone database backup
|
||||
- `./db-backup--swarm.sh` - Run swarm database backup
|
||||
- `./db-dump--standalone.sh` - Run standalone database dump
|
||||
- See housekeeping/README.md for more details
|
||||
|
||||
## Deployment Commands
|
||||
|
||||
- `./build.sh` - Build Docker image for deployment
|
||||
- `./deploy.sh` - Deploy Docker service to production
|
||||
- `./debug-deploy.sh` - Deploy with debug configuration
|
||||
**Building Docker Image** (`cd web-app`):
|
||||
- `./build.sh <version>` - Build Docker image
|
||||
|
||||
**Deploying** (`cd docker-stack`):
|
||||
- `./deploy-standalone.sh <version>` - Deploy with docker-compose (standalone)
|
||||
- `./deploy-swarm.sh <version>` - Deploy with Docker Swarm
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
@@ -31,25 +52,26 @@ This is a Next.js 14 utility bills tracking application ("Evidencija Režija") w
|
||||
|
||||
### Core Architecture Patterns
|
||||
|
||||
**Multi-user Data Isolation**: All database operations use the `withUser` higher-order function from `app/lib/auth.ts:102` to automatically inject authenticated user ID into queries, ensuring data isolation between users.
|
||||
**Multi-user Data Isolation**: All database operations use the `withUser` higher-order function from `web-app/app/lib/auth.ts:102` to automatically inject authenticated user ID into queries, ensuring data isolation between users.
|
||||
|
||||
**Server Actions Pattern**: Form handling uses Next.js Server Actions with Zod validation. Actions are defined in `app/lib/actions/` and follow the pattern:
|
||||
**Server Actions Pattern**: Form handling uses Next.js Server Actions with Zod validation. Actions are defined in `web-app/app/lib/actions/` and follow the pattern:
|
||||
```typescript
|
||||
export const actionName = withUser(async (user: AuthenticatedUser, ...args) => {
|
||||
// Server action implementation with automatic user context
|
||||
});
|
||||
```
|
||||
|
||||
**Internationalization**: Uses next-intl with locale-based routing. Messages are in `messages/` directory. The middleware handles both auth and i18n routing.
|
||||
**Internationalization**: Uses next-intl with locale-based routing. Messages are in `web-app/messages/` directory. The middleware handles both auth and i18n routing.
|
||||
|
||||
### Key Files & Responsibilities
|
||||
|
||||
- `middleware.ts` - Handles authentication and i18n routing, defines public pages
|
||||
- `app/lib/auth.ts` - NextAuth configuration, `withUser` HOF for user context
|
||||
- `app/lib/dbClient.ts` - MongoDB connection with development/production handling
|
||||
- `app/lib/actions/` - Server actions for data mutations (locations, bills, months)
|
||||
- `app/i18n.ts` - Internationalization configuration (Croatian default)
|
||||
- `next.config.js` - Standalone build config with `serverActions.allowedOrigins` for Docker deployment
|
||||
- `web-app/middleware.ts` - Handles authentication and i18n routing, defines public pages
|
||||
- `web-app/app/lib/auth.ts` - NextAuth configuration, `withUser` HOF for user context
|
||||
- `web-app/app/lib/dbClient.ts` - MongoDB connection with development/production handling
|
||||
- `web-app/app/lib/actions/` - Server actions for data mutations (locations, bills, months)
|
||||
- `web-app/app/i18n.ts` - Internationalization configuration (Croatian default)
|
||||
- `web-app/next.config.js` - Standalone build config with `serverActions.allowedOrigins` for Docker deployment
|
||||
- `housekeeping/` - Database backup and maintenance scripts
|
||||
|
||||
### Database Schema
|
||||
- **Collections**: Locations, Bills, Months (year-month periods)
|
||||
|
||||
81
README.md
@@ -17,46 +17,74 @@ Each location record is marked with a user ID.
|
||||
|
||||
All the actions user `withUser` to fetch user ID, which is then used in all the DB operations.
|
||||
|
||||
# Repository Structure
|
||||
|
||||
This repository contains multiple independent projects:
|
||||
|
||||
- **web-app/**: Next.js application for tracking utility bills
|
||||
- **docker-stack/**: Docker Compose configurations and deployment scripts
|
||||
- **housekeeping/**: Database backup and maintenance scripts
|
||||
|
||||
Each project is self-contained with its own dependencies and configuration.
|
||||
|
||||
## Working with Projects
|
||||
|
||||
```bash
|
||||
# Web app
|
||||
cd web-app
|
||||
npm install
|
||||
npm run dev
|
||||
|
||||
# Deploy with Docker
|
||||
cd docker-stack
|
||||
./deploy-standalone.sh 2.20.0
|
||||
|
||||
# Housekeeping scripts
|
||||
cd housekeeping
|
||||
./db-backup--standalone.sh
|
||||
```
|
||||
|
||||
# Database Backup & Restore
|
||||
|
||||
The project includes multiple backup strategies for different deployment scenarios and requirements.
|
||||
All backup scripts are located in the `housekeeping/` workspace.
|
||||
|
||||
## Backup Scripts Overview
|
||||
|
||||
### Standalone Docker Deployments
|
||||
|
||||
**Online Backups (No Downtime):**
|
||||
- `db-dump--standalone.sh` - Creates online backup of the 'utility-bills' database using mongodump
|
||||
- `housekeeping/db-dump--standalone.sh` - Creates online backup of the 'utility-bills' database using mongodump
|
||||
- Database stays running during backup
|
||||
- Only backs up the database content, not the full volume
|
||||
- Output: `./mongo-backup/utility-bills-dump-YYYY-MM-DD_HH-MM.tar.gz`
|
||||
- Default retention: 7 backups (configurable via `KEEP` env var)
|
||||
- Usage: `./db-dump--standalone.sh` or `KEEP=10 ./db-dump--standalone.sh`
|
||||
- Usage: `cd housekeeping && ./db-dump--standalone.sh` or `KEEP=10 ./db-dump--standalone.sh`
|
||||
|
||||
- `db-restore-from-dump--standalone.sh` - Restores from mongodump archives
|
||||
- `housekeeping/db-restore-from-dump--standalone.sh` - Restores from mongodump archives
|
||||
- Database stays running during restore
|
||||
- **WARNING**: Drops existing collections before restore
|
||||
- Usage: `./db-restore-from-dump--standalone.sh utility-bills-dump-2025-11-26_14-30.tar.gz`
|
||||
- Usage: `cd housekeeping && ./db-restore-from-dump--standalone.sh utility-bills-dump-2025-11-26_14-30.tar.gz`
|
||||
|
||||
**Offline Backups (With Downtime):**
|
||||
- `db-backup--standalone.sh` - Creates offline backup of the complete mongo-volume directory
|
||||
- `housekeeping/db-backup--standalone.sh` - Creates offline backup of the complete mongo-volume directory
|
||||
- Database container is stopped during backup for consistency
|
||||
- Backs up the entire MongoDB data directory
|
||||
- Output: `./mongo-backup/mongo-volume-backup-YYYY-MM-DD-HH-MM.tar.gz`
|
||||
- Default retention: 7 backups (configurable via `KEEP` env var)
|
||||
- Usage: `./db-backup--standalone.sh` or `KEEP=2 ./db-backup--standalone.sh`
|
||||
- Usage: `cd housekeeping && ./db-backup--standalone.sh` or `KEEP=2 ./db-backup--standalone.sh`
|
||||
|
||||
### Docker Swarm Deployments
|
||||
|
||||
- `db-backup--swarm.sh` - Creates offline backup by scaling down the MongoDB service
|
||||
- `housekeeping/db-backup--swarm.sh` - Creates offline backup by scaling down the MongoDB service
|
||||
- Service is scaled to 0 during backup
|
||||
- Output: `./mongo-backup/mongo-volume-backup-YYYY-MM-DD-HH-MM.tar.gz`
|
||||
- Usage: `./db-backup--swarm.sh`
|
||||
- Usage: `cd housekeeping && ./db-backup--swarm.sh`
|
||||
|
||||
- `db-restore-from-backup--swarm.sh` - Restores volume backup by scaling down the service
|
||||
- `housekeeping/db-restore-from-backup--swarm.sh` - Restores volume backup by scaling down the service
|
||||
- Service is scaled to 0 during restore
|
||||
- Optional `--pre-backup` flag for safety backup before restore
|
||||
- Usage: `./db-restore-from-backup--swarm.sh mongo-volume-backup-2025-11-26-14-30.tar.gz`
|
||||
- Usage: `cd housekeeping && ./db-restore-from-backup--swarm.sh mongo-volume-backup-2025-11-26-14-30.tar.gz`
|
||||
|
||||
## Automated Backup Schedule
|
||||
|
||||
@@ -64,10 +92,10 @@ Backups run automatically via cron at 04:00 every day:
|
||||
|
||||
```cron
|
||||
# Sunday: Full volume backup (offline), keep 2 backups
|
||||
0 4 * * 0 cd /home/knee-cola/web-pro/evidencija-rezija && KEEP=2 ./db-backup--standalone.sh
|
||||
0 4 * * 0 cd /home/knee-cola/web-pro/evidencija-rezija/housekeeping && KEEP=2 ./db-backup--standalone.sh
|
||||
|
||||
# Monday-Saturday: Database dump (online), keep 6 backups
|
||||
0 4 * * 1-6 cd /home/knee-cola/web-pro/evidencija-rezija && KEEP=6 ./db-dump--standalone.sh
|
||||
0 4 * * 1-6 cd /home/knee-cola/web-pro/evidencija-rezija/housekeeping && KEEP=6 ./db-dump--standalone.sh
|
||||
```
|
||||
|
||||
**Backup Strategy:**
|
||||
@@ -89,21 +117,32 @@ All backups are stored in `./mongo-backup/`:
|
||||
This directory is excluded from git via `.gitignore`.
|
||||
|
||||
# Deploying
|
||||
The deployment is done via Docker:
|
||||
* build docker image
|
||||
* deploy Docker service
|
||||
|
||||
## Building Docker image
|
||||
Run the following command:
|
||||
The deployment is done via Docker.
|
||||
|
||||
## Building Docker Image
|
||||
|
||||
From the `web-app/` directory:
|
||||
|
||||
```bash
|
||||
build.sh
|
||||
cd web-app
|
||||
./build.sh 2.20.0
|
||||
```
|
||||
|
||||
The image will be stored in the local Docker instance.
|
||||
|
||||
## Deploying Docker service
|
||||
Run the following command:
|
||||
## Deploying Docker Service
|
||||
|
||||
From the `docker-stack/` directory:
|
||||
|
||||
```bash
|
||||
deploy.sh
|
||||
cd docker-stack
|
||||
|
||||
# Standalone deployment
|
||||
./deploy-standalone.sh 2.20.0
|
||||
|
||||
# Or Swarm deployment
|
||||
./deploy-swarm.sh 2.20.0
|
||||
```
|
||||
|
||||
# Implementation details
|
||||
|
||||
46
docker-stack/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Docker Stack
|
||||
|
||||
Docker Compose configurations and deployment scripts for the Evidencija Režija application.
|
||||
|
||||
## Files
|
||||
|
||||
### Docker Compose Configurations
|
||||
|
||||
- `docker-compose-standalone.yaml` - Standalone deployment with docker-compose
|
||||
- `docker-compose-swarm.yml` - Docker Swarm deployment
|
||||
- `docker-compose-debug.yml` - Debug/development deployment
|
||||
|
||||
### Deployment Scripts
|
||||
|
||||
- `deploy-standalone.sh` - Deploy standalone configuration
|
||||
- `deploy-swarm.sh` - Deploy swarm configuration
|
||||
|
||||
## Usage
|
||||
|
||||
### Deploying Standalone
|
||||
|
||||
```bash
|
||||
cd docker-stack
|
||||
./deploy-standalone.sh 2.20.0
|
||||
```
|
||||
|
||||
### Deploying to Swarm
|
||||
|
||||
```bash
|
||||
cd docker-stack
|
||||
./deploy-swarm.sh 2.20.0
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker image must be built first: `cd ../web-app && ./build.sh 2.20.0`
|
||||
- MongoDB data directory: `../mongo-volume/`
|
||||
- MongoDB backup directory: `../mongo-backup/`
|
||||
|
||||
## Configuration
|
||||
|
||||
All compose files reference:
|
||||
- Web app image: `utility-bills-tracker:${IMAGE_VERSION}`
|
||||
- Volume mounts: `../web-app/etc/hosts/`
|
||||
- MongoDB data: `../mongo-volume/`
|
||||
- MongoDB backups: `../mongo-backup/`
|
||||
@@ -18,7 +18,7 @@ services:
|
||||
- traefik-network
|
||||
- util-bills-mongo-network
|
||||
volumes:
|
||||
- ./etc/hosts/:/etc/hosts
|
||||
- ./web-app/etc/hosts/:/etc/hosts
|
||||
environment:
|
||||
MONGODB_URI: mongodb://rezije.app:w4z4piJBgCdAm4tpawqB@mongo:27017/utility-bills
|
||||
GOOGLE_ID: 355397364527-adjrokm6hromcaaar0qfhk050mfr35ou.apps.googleusercontent.com
|
||||
@@ -18,7 +18,7 @@ services:
|
||||
- traefik-network
|
||||
- util-bills-mongo-network
|
||||
volumes:
|
||||
- ./etc/hosts/:/etc/hosts
|
||||
- ./web-app/etc/hosts/:/etc/hosts
|
||||
environment:
|
||||
MONGODB_URI: mongodb://rezije.app:w4z4piJBgCdAm4tpawqB@mongo:27017/utility-bills
|
||||
GOOGLE_ID: 355397364527-adjrokm6hromcaaar0qfhk050mfr35ou.apps.googleusercontent.com
|
||||
10
docker-stack/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "docker-stack",
|
||||
"version": "2.20.0",
|
||||
"private": true,
|
||||
"description": "Docker deployment configurations and scripts",
|
||||
"scripts": {
|
||||
"deploy:standalone": "./deploy-standalone.sh",
|
||||
"deploy:swarm": "./deploy-swarm.sh"
|
||||
}
|
||||
}
|
||||
43
evidencija-rezija.code-workspace
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "🌐 web-app",
|
||||
"path": "web-app"
|
||||
},
|
||||
{
|
||||
"name": "🐳 docker-stack",
|
||||
"path": "docker-stack"
|
||||
},
|
||||
{
|
||||
"name": "🔧 housekeeping",
|
||||
"path": "housekeeping"
|
||||
},
|
||||
{
|
||||
"name": "📦 root",
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"files.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/.next": true,
|
||||
"**/.git": false
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/.next": true,
|
||||
"**/package-lock.json": true
|
||||
},
|
||||
"typescript.tsdk": "web-app/node_modules/typescript/lib",
|
||||
"eslint.workingDirectories": [
|
||||
"web-app"
|
||||
]
|
||||
},
|
||||
"extensions": {
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"bradlc.vscode-tailwindcss"
|
||||
]
|
||||
}
|
||||
}
|
||||
20
housekeeping/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Housekeeping
|
||||
|
||||
Database backup and maintenance scripts for the Evidencija Režija application.
|
||||
|
||||
## Scripts
|
||||
|
||||
- `db-backup--standalone.sh` - Backup database in standalone deployment
|
||||
- `db-backup--swarm.sh` - Backup database in Docker Swarm deployment
|
||||
- `db-dump--standalone.sh` - Dump database in standalone deployment
|
||||
- `db-restore-from-dump--standalone.sh` - Restore from dump in standalone deployment
|
||||
- `db-restore-from-backup--swarm.sh` - Restore from backup in Docker Swarm deployment
|
||||
|
||||
## Usage
|
||||
|
||||
From the housekeeping directory:
|
||||
|
||||
```bash
|
||||
cd housekeeping
|
||||
./db-backup--standalone.sh
|
||||
```
|
||||
13
housekeeping/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "housekeeping",
|
||||
"version": "2.20.0",
|
||||
"private": true,
|
||||
"description": "Database backup and maintenance scripts",
|
||||
"scripts": {
|
||||
"backup:standalone": "./db-backup--standalone.sh",
|
||||
"backup:swarm": "./db-backup--swarm.sh",
|
||||
"dump:standalone": "./db-dump--standalone.sh",
|
||||
"restore:standalone": "./db-restore-from-dump--standalone.sh",
|
||||
"restore:swarm": "./db-restore-from-backup--swarm.sh"
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"name": "Debug",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"envFile": "${workspaceFolder:🌐 web-app}/.env",
|
||||
"env": {
|
||||
"USE_MOCK_AUTH": "true",
|
||||
"MOCK_USER_ID": "109754742613069927799",
|
||||
@@ -19,8 +19,8 @@
|
||||
"dev" // this is `dev` from `npm run dev`
|
||||
],
|
||||
"runtimeExecutable": "npm",
|
||||
"cwd": "${workspaceFolder}/",
|
||||
"localRoot": "${workspaceFolder}/",
|
||||
"cwd": "${workspaceFolder:🌐 web-app}/",
|
||||
"localRoot": "${workspaceFolder:🌐 web-app}/",
|
||||
"remoteRoot": "/app/",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**",
|
||||
@@ -13,7 +13,7 @@
|
||||
"build": true,
|
||||
},
|
||||
"files": [
|
||||
"${workspaceFolder}/docker-compose-debug.yml"
|
||||
"${workspaceFolder:🌐 web-app}/docker-compose-debug.yml"
|
||||
],
|
||||
"isBackground": true,
|
||||
"problemMatcher": "Terminal will be reused by tasks, press any key to close it"
|
||||
@@ -25,7 +25,7 @@
|
||||
"dockerCompose": {
|
||||
"down": {},
|
||||
"files": [
|
||||
"${workspaceFolder}/docker-compose-debug.yml"
|
||||
"${workspaceFolder:🌐 web-app}/docker-compose-debug.yml"
|
||||
],
|
||||
}
|
||||
},
|
||||
@@ -12,16 +12,16 @@ RUN apk add --no-cache libc6-compat
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# package.json and package-lock.json
|
||||
# Copy package files
|
||||
COPY ./package.json ./package-lock.json ./
|
||||
|
||||
# installing dependencies
|
||||
# Install dependencies
|
||||
RUN npm i && npm cache clean --force
|
||||
|
||||
# copy all the soruce code
|
||||
# Copy application source code
|
||||
COPY . .
|
||||
|
||||
# building app
|
||||
# Build application
|
||||
RUN npm run build
|
||||
|
||||
#-----------------------------------------
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |