Skip to content

CFS Platform - Monorepo Migration Workflow

Overview

This workflow describes the step-by-step migration of the ZWB (Zuwendungsbestätigung) generator into a monorepo architecture and the development of new modules (mailing, newsletter) using Antigravity.


Target Architecture

cfs-platform/                        # Monorepo Root
├── apps/                            # Independent Applications
│   ├── portal/                      # Shell with Dashboard + Navigation
│   ├── zuwendung/                   # Existing ZWB Generator App
│   ├── mailing/                     # Bulk Mailing Tool (new)
│   └── newsletter/                  # Newsletter Generator (new)

├── packages/                        # Shared Code
│   ├── database/                    # Central Database Logic + Models
│   ├── ui-components/               # Shared UI + Style Guide
│   ├── auth/                        # Shared Authentication
│   └── utils/                       # Shared Utilities

├── docker/                          # Docker Setup
│   ├── docker-compose.yml
│   ├── docker-compose.dev.yml
│   ├── docker-compose.prod.yml
│   ├── nginx.conf
│   ├── start.sh
│   └── README.md

├── docs/                            # Documentation
│   ├── architecture.md
│   ├── development.md
│   └── deployment.md

├── .github/                         # GitHub Workflows
│   └── workflows/
│       ├── ci.yml
│       └── deploy.yml

├── package.json                     # Root Package (Workspaces)
├── .gitignore
├── .gitattributes
└── README.md

Architectural Principles

1. Monorepo with npm Workspaces

  • One repository for all apps and packages.
  • Shared code centralized under packages/.
  • Independent development per application workspace.

2. App-Shell Architecture

  • One domain (domain.de).
  • Central navigation (sidebar replicated in all apps).
  • Modules organized under subpaths (/zuwendung, /mailing).
  • Nginx reverse proxy handling routing.

3. Shared Components

  • All applications import from @cfs-platform/ui-components.
  • Consistent brand styling via unified Style Guide.
  • AppShell component for a standardized layout.

4. Centralized Database

  • Single MariaDB/MySQL database.
  • All applications use @cfs-platform/database.
  • Customers table serves as the central CMS index.

5. Git-Based Version Control

  • GitHub for central codebase management.
  • Feature branches for new functionality.
  • main branch reserved for stable production.
  • develop branch for integration testing.

Migration Phases

Phase 0a: Preparation (Manual)

Tasks:

  1. Back up Production Version:

    bash
    cp -r /path/to/zwb-generator /path/to/zwb-generator-BACKUP
  2. Create Working Copy:

    bash
    cp -r /path/to/zwb-generator /path/to/zwb-generator-migration
  3. Initialize New Monorepo Directory:

    bash
    mkdir cfs-platform
    cd cfs-platform
  4. Prepare Style Guide:

    • Ensure your Style Guide assets are accessible.
    • Note the path to the Style Guide for Prompt #4a.

Checklist:

  • [ ] Backup created
  • [ ] Working copy created
  • [ ] Monorepo folder initialized
  • [ ] Style Guide path noted
  • [ ] Antigravity ready

Phase 0b: Git/GitHub Setup

Tasks:

  1. Create GitHub Repository:

    • Navigate to https://github.com/new
    • Repository Name: cfs-platform
    • Description: "Multi-App Platform for Zuwendungen, Mailing & Newsletter"
    • Visibility: Private (recommended)
    • DO NOT initialize with a README, .gitignore, or License.
    • Click Create.
  2. Initialize Local Git:

    bash
    cd cfs-platform
    git init
    git branch -M main
  3. Add Remote Origin:

    bash
    # Replace USERNAME with your GitHub username
    git remote add origin https://github.com/USERNAME/cfs-platform.git
  4. Verify Git Configuration:

    bash
    git config user.name "Christian Friedrich Schacht"
    git config user.email "your@email.com"

Checklist:

  • [ ] GitHub repository created
  • [ ] Git initialized locally
  • [ ] Remote origin connected
  • [ ] Git configuration set

Phase 1: Initialize Monorepo Structure

Antigravity Prompt #1:

text
Create a monorepo structure for a multi-app platform meeting the following requirements:

STRUCTURE:
- Root directory: cfs-platform/
- Subdirectories: apps/, packages/, docker/, docs/, .github/
- Package Manager: npm workspaces

FILES TO CREATE:

1. package.json (Root) with Workspace configuration:
{
  "name": "cfs-platform",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "install:all": "npm install",
    "dev:portal": "npm run dev --workspace=@cfs-platform/portal",
    "dev:zuwendung": "npm run dev --workspace=@cfs-platform/zuwendung",
    "dev:mailing": "npm run dev --workspace=@cfs-platform/mailing",
    "build:all": "npm run build --workspaces",
    "test:all": "npm run test --workspaces",
    "lint:all": "npm run lint --workspaces"
  },
  "devDependencies": {
    "eslint": "^8.0.0",
    "prettier": "^3.0.0"
  }
}

2. .gitignore:
# Dependencies
node_modules/
package-lock.json

# Build outputs
dist/
build/
.next/
out/

# Environment
.env
.env.local
.env.*.local

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# OS
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# Docker
docker/volumes/

# Testing
coverage/
.nyc_output/

# Temporary
tmp/
temp/

3. .gitattributes:
# Auto detect text files and perform LF normalization
* text=auto

# Explicitly declare text files
*.js text
*.jsx text
*.json text
*.md text
*.yml text
*.yaml text

# Denote all files that are truly binary
*.png binary
*.jpg binary
*.pdf binary

4. README.md:
# CFS Platform

Multi-app platform for donation confirmations (Zuwendungen), bulk email, and newsletter management.

## Architecture

Monorepo utilizing npm Workspaces:
- **apps/**: Independent web applications.
- **packages/**: Shared modules (Database, UI, Utils).
- **docker/**: Docker configuration for development and production.

## Apps

- **portal**: Dashboard and centralized navigation hub.
- **zuwendung**: Spendenbescheinigung PDF generator.
- **mailing**: Bulk email campaign distribution tool.
- **newsletter**: Drag-and-drop newsletter builder and publisher.

## Shared Packages

- **@cfs-platform/database**: Central database models and repository logic.
- **@cfs-platform/ui-components**: Shared UI library and style guide implementation.
- **@cfs-platform/auth**: Authentication and authorization utilities.
- **@cfs-platform/utils**: Shared utility helpers (validators, formatters, logger).

## Setup

### Prerequisites
- Node.js 18+
- npm 9+
- Docker & Docker Compose

### Installation

```bash
# Install dependencies
npm run install:all

# Start local environment
cd docker
./start.sh
```

### Development

```bash
# Run portal app
npm run dev:portal

# Run donation app
npm run dev:zuwendung

# Build all applications
npm run build:all
```

## Deployment

Refer to [docs/deployment.md](docs/deployment.md)

## License

Proprietary - Christian Friedrich Schacht

5. docs/architecture.md:
# Architecture Documentation

## Monorepo Concept

The CFS Platform project leverages a monorepo structure with npm Workspaces.

### Key Benefits

- **Code Sharing**: Shared packages are naturally referenced by all applications without npm registry publishing overhead.
- **Consistent Dependencies**: Enforced through a single package-lock.json at the root level.
- **Atomic Commits**: Allows synchronized changes across packages and apps in a single commit.
- **Seamless Refactoring**: Adjustments made to shared packages are instantly propagated across all importing apps.

## App-Shell Architecture

All apps embed a unified sidebar navigation component (AppShell):
- Central sidebar navigation menu.
- Reusable page layouts (Header, Footer).
- Integrated authentication validation.

### Routing

An Nginx reverse proxy routes internal application entry points:
- `/` → Portal Shell Application
- `/zuwendung` → Donation Application
- `/mailing` → Bulk Mailing Module
- `/newsletter` → Newsletter Generator

## Database Architecture

A central, unified MariaDB/MySQL database:
- `customers`: Main client table (serves as the primary CMS index).
- `donations`: Transaction records for the donation PDF generator.
- `email_campaigns`: Campaigns dispatched by the mailing tool.
- `newsletters`: Metadata and templates for the newsletter editor.

All apps interact with the database via the `@cfs-platform/database` shared workspace package.

## Deployment Strategy

### Development
- Docker Compose local environment with hot-reloading active.
- Dedicated local database instance.

### Production
- VPS Docker Compose orchestration.
- Nginx operating as the primary reverse proxy.
- SSL/TLS certification automated via Let's Encrypt.
- Automated daily incremental backup scripts.

6. docs/development.md:
# Development Guide

## Adding a New Application

1. Initialize folder structure: `apps/new-app/`
2. Configure package.json using name `@cfs-platform/new-app`
3. Integrate the AppShell layouts.
4. Register the module under `packages/ui-components/src/config/modules.json`
5. Configure the local Docker service inside `docker/docker-compose.dev.yml`
6. Add the routing configuration rule inside `docker/nginx.conf`

## Adding a New Shared Package

1. Initialize folder structure: `packages/new-package/`
2. Configure package.json using name `@cfs-platform/new-package`
3. Define workspace exports inside `src/index.js`
4. Import within workspaces: `import { ... } from '@cfs-platform/new-package'`

## Git Workflow

### Feature Branching

```bash
# Create a fresh branch
git checkout -b feature/new-capability

# Commit your changes
git add .
git commit -m "feat: implement new capability"

# Push to origin
git push origin feature/new-capability

# Open a Pull Request on GitHub
```

### Commit Guidelines

- `feat:` Introduces brand-new capabilities.
- `fix:` Fixes bugs or resolves crashes.
- `docs:` Documentation-only updates.
- `style:` Code style modifications (formatting, white-space).
- `refactor:` Restructuring code without changing functionality.
- `test:` Adding or adjusting unit/integration test suites.
- `chore:` Maintenance, builds, or workflow configurations.

## Testing

```bash
# Execute tests across the entire repository
npm run test:all

# Execute tests for a specific workspace app
npm run test --workspace=@cfs-platform/zuwendung
```

## Linting

```bash
# Execute static analysis and linting
npm run lint:all
```

7. docs/deployment.md:
# Deployment Guide

## VPS Environment Preparation

### Prerequisites
- Ubuntu 22.04 LTS
- Docker & Docker Compose CLI installed
- Active Domain pointing to the VPS IP

### Server Setup

```bash
# Install Docker Engine
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Install Docker Compose Plugin
sudo apt install docker-compose-plugin

# Append active user to the docker group
sudo usermod -aG docker $USER
```

## Deployment Steps

### 1. Synchronize Code to Server

```bash
# SSH into the VPS
ssh user@your-vps.com

# Clone the codebase
git clone https://github.com/USERNAME/cfs-platform.git
cd cfs-platform
```

### 2. Configure Environment

```bash
# Create environment variables file
cp .env.example .env
nano .env

# Configure target credentials:
DB_ROOT_PASSWORD=highly_secure_root_password
DB_NAME=cfs_platform
DB_USER=cfs_user
DB_PASSWORD=highly_secure_user_password
```

### 3. Orchestrate Stack

```bash
cd docker
docker-compose -f docker-compose.prod.yml up -d
```

### 4. Configure SSL/TLS Certificates

```bash
# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Request certificate validation
sudo certbot --nginx -d yourdomain.com
```

## Platform Updates

```bash
# Fetch latest branch developments
git pull origin main

# Re-orchestrate running services
cd docker
docker-compose -f docker-compose.prod.yml up -d --build
```

## Data Backup and Restores

```bash
# Output database contents
docker exec cfs_database_prod mysqldump -u root -p cfs_platform > backup.sql

# Restore from backup snapshot
docker exec -i cfs_database_prod mysql -u root -p cfs_platform < backup.sql
```

8. .github/workflows/ci.yml:
name: CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'

    - name: Install dependencies
      run: npm ci

    - name: Lint
      run: npm run lint:all

    - name: Test
      run: npm run test:all

    - name: Build
      run: npm run build:all

9. .github/workflows/deploy.yml:
name: Deploy to VPS

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Deploy to VPS
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.VPS_HOST }}
        username: ${{ secrets.VPS_USER }}
        key: ${{ secrets.VPS_SSH_KEY }}
        script: |
          cd /var/www/cfs-platform
          git pull origin main
          cd docker
          docker-compose -f docker-compose.prod.yml up -d --build

Initialize the entire folder structure with the specified files.

Post-Prompt #1 - Git Commit:

bash
# Check status
git status

# Stage all files
git add .

# Initial Commit
git commit -m "chore: Initial monorepo structure"

# Push to GitHub
git push -u origin main

Testing:

bash
cd cfs-platform
npm install
# Should complete successfully without errors

# Check Git log
git log --oneline
# Should display the initial commit

Checklist:

  • [ ] Folder structure initialized
  • [ ] Root package.json workspaces configured
  • [ ] .gitignore added
  • [ ] README.md documented
  • [ ] GitHub actions CI/CD workflows added
  • [ ] npm install runs successfully
  • [ ] Initial Git commit completed
  • [ ] Pushed to GitHub repository

Phase 2: Migrate ZWB Generator

Antigravity Prompt #2:

text
Migrate the existing ZWB generator application workspace into the monorepo structure:

SOURCE:
/path/to/zwb-generator-migration/

TARGET:
cfs-platform/apps/zuwendung/

TASKS:
1. Copy all workspace files from source into apps/zuwendung/
2. Maintain existing directory layout structures (src/, public/, etc.)
3. Adjust package.json config:
   - Name: "@cfs-platform/zuwendung"
   - Version: "1.0.0"
   - Remove "workspaces" key (since it is a sub-package now)
4. Create apps/zuwendung/README.md containing:
   - Module descriptions
   - Available capabilities
   - Development command sets
5. Validate all relative package imports and path references remain correct.

IMPORTANT:
- Absolutely no logic or functional modifications to the source code.
- Workspace must operate identically to its pre-migration status.
- Ignore Docker configurations for now (addressed in Phase 7).
- Keep existing dependencies declared inside the package.json.

Post-Prompt #2 - Git Commit:

bash
# Create feature branch
git checkout -b feature/migrate-zuwendung

# Stage migration files
git add apps/zuwendung/

# Commit
git commit -m "feat: Migrate ZWB-Generator to monorepo"

# Push
git push -u origin feature/migrate-zuwendung

Testing:

bash
cd apps/zuwendung
npm install
npm run dev
# App should operate flawlessly as before

Checklist:

  • [ ] All source files copied
  • [ ] package.json successfully adjusted
  • [ ] README.md added
  • [ ] npm install runs successfully
  • [ ] Application dev server launches and operates
  • [ ] Git commit generated
  • [ ] Branch pushed to remote

Phase 3: Integrate Style Guide

Antigravity Prompt #3:

text
Prepare the Style Guide integration inside the shared packages workspace:

SOURCE:
[INSERT PATH TO THE BRAND STYLE GUIDE ASSETS]

TARGET:
packages/ui-components/

CREATE STRUCTURE:
packages/ui-components/
├── src/
│   ├── components/
│   ├── styles/
│   │   ├── design-tokens.json
│   │   ├── variables.css
│   │   └── global.css
│   └── index.js
├── styleguide/
│   └── [Style Guide Asset Files]
├── package.json
└── README.md

TASKS:

1. COPY STYLE GUIDE:
Copy all brand style guide assets into packages/ui-components/styleguide/

2. EXTRACT DESIGN TOKENS:
Create packages/ui-components/src/styles/design-tokens.json

Analyze the provided style guide assets and extract standard parameters:
{
  "colors": {
    "primary": "...",
    "secondary": "...",
    "error": "...",
    "success": "...",
    "warning": "...",
    "text": {
      "primary": "...",
      "secondary": "...",
      "disabled": "..."
    },
    "background": {
      "default": "...",
      "paper": "...",
      "elevated": "..."
    },
    "border": {
      "default": "...",
      "light": "..."
    }
  },
  "typography": {
    "fontFamily": {
      "primary": "...",
      "secondary": "...",
      "mono": "..."
    },
    "fontSize": {
      "xs": "...",
      "sm": "...",
      "md": "...",
      "lg": "...",
      "xl": "...",
      "2xl": "..."
    },
    "fontWeight": {
      "light": "...",
      "normal": "...",
      "medium": "...",
      "semibold": "...",
      "bold": "..."
    },
    "lineHeight": {
      "tight": "...",
      "normal": "...",
      "relaxed": "..."
    }
  },
  "spacing": {
    "xs": "...",
    "sm": "...",
    "md": "...",
    "lg": "...",
    "xl": "...",
    "2xl": "..."
  },
  "shadows": {
    "sm": "...",
    "md": "...",
    "lg": "...",
    "xl": "..."
  },
  "borderRadius": {
    "none": "0",
    "sm": "...",
    "md": "...",
    "lg": "...",
    "full": "9999px"
  },
  "transitions": {
    "fast": "...",
    "normal": "...",
    "slow": "..."
  }
}

3. CSS CUSTOM PROPERTIES:
Create packages/ui-components/src/styles/variables.css

Convert the values inside design-tokens.json into CSS Custom Properties variables:
:root {
  /* Colors */
  --color-primary: [from tokens];
  --color-secondary: [from tokens];
  --color-error: [from tokens];
  --color-success: [from tokens];
  --color-text-primary: [from tokens];
  --color-text-secondary: [from tokens];
  --color-background-default: [from tokens];
  --color-background-paper: [from tokens];
  --color-border-default: [from tokens];

  /* Typography */
  --font-family-primary: [from tokens];
  --font-family-mono: [from tokens];
  --font-size-xs: [from tokens];
  --font-size-sm: [from tokens];
  --font-size-md: [from tokens];
  --font-size-lg: [from tokens];
  --font-weight-normal: [from tokens];
  --font-weight-medium: [from tokens];
  --font-weight-bold: [from tokens];
  --line-height-normal: [from tokens];

  /* Spacing */
  --spacing-xs: [from tokens];
  --spacing-sm: [from tokens];
  --spacing-md: [from tokens];
  --spacing-lg: [from tokens];
  --spacing-xl: [from tokens];

  /* Shadows */
  --shadow-sm: [from tokens];
  --shadow-md: [from tokens];
  --shadow-lg: [from tokens];

  /* Border Radius */
  --border-radius-sm: [from tokens];
  --border-radius-md: [from tokens];
  --border-radius-lg: [from tokens];

  /* Transitions */
  --transition-fast: [from tokens];
  --transition-normal: [from tokens];
}

4. GLOBAL STYLES:
Create packages/ui-components/src/styles/global.css

@import './variables.css';

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-family-primary);
  font-size: var(--font-size-md);
  line-height: var(--line-height-normal);
  color: var(--color-text-primary);
  background-color: var(--color-background-default);
}

h1, h2, h3, h4, h5, h6 {
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

a {
  color: var(--color-primary);
  text-decoration: none;
  transition: color var(--transition-fast);
}

a:hover {
  color: var(--color-secondary);
}

5. PACKAGE.JSON:
{
  "name": "@cfs-platform/ui-components",
  "version": "1.0.0",
  "main": "src/index.js",
  "dependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}

6. README.md:
Create packages/ui-components/README.md containing:
- High-level overview of the UI Design Tokens component ecosystem
- How to consume design tokens inside CSS files
- Component import patterns
- Style Guide compliance patterns
- Basic code examples demonstrating clean components

7. INDEX.JS:
Create packages/ui-components/src/index.js:
// Styles
export * from './styles/design-tokens.json';

// Note: Reusable UI Components will be exported here in Phase 4

Post-Prompt #3 - Git Commit:

bash
# Stage UI components workspace
git add packages/ui-components/

# Commit
git commit -m "feat: Add style guide and design tokens"

# Push branch
git push origin feature/migrate-zuwendung

Testing:

bash
cd packages/ui-components
npm install
# Verify design tokens output matches style guide spec
cat src/styles/design-tokens.json

Checklist:

  • [ ] Style Guide assets placed inside directory
  • [ ] design-tokens.json generated and validated
  • [ ] variables.css configured using tokens variables
  • [ ] global.css created and base selectors set
  • [ ] package.json configured
  • [ ] README.md completed
  • [ ] Git commit successfully made

Phase 4: Extract Shared Packages

Antigravity Prompt #4a - Database Package:

text
Extract the database orchestration logic out of apps/zuwendung/ into a clean, reusable shared package:

PACKAGE: @cfs-platform/database
TARGET: packages/database/

STRUCTURE:
packages/database/
├── src/
│   ├── models/
│   │   ├── Customer.js
│   │   ├── Donation.js
│   │   └── index.js
│   ├── migrations/
│   ├── connection.js
│   ├── config.js
│   └── index.js
├── package.json
└── README.md

TASKS:

1. MODEL EXTRACTION:
Locate all active database models declared in apps/zuwendung/src/ and copy them to packages/database/src/models/

Example of target models setup (Customer.js):
// packages/database/src/models/Customer.js
const { DataTypes } = require('sequelize');

module.exports = (sequelize) => {
  const Customer = sequelize.define('Customer', {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
    },
    salutation: {
      type: DataTypes.STRING,
      allowNull: true
    },
    address: {
      type: DataTypes.TEXT,
      allowNull: true
    }
  });

  return Customer;
};

2. CONNECTION MANAGEMENT:
Create packages/database/src/connection.js:
const { Sequelize } = require('sequelize');
const config = require('./config');

const sequelize = new Sequelize(
  config.database,
  config.username,
  config.password,
  {
    host: config.host,
    dialect: 'mysql',
    logging: config.logging
  }
);

module.exports = sequelize;

3. CONFIGURATION MANAGEMENT:
Create packages/database/src/config.js:
module.exports = {
  host: process.env.DB_HOST || 'localhost',
  database: process.env.DB_NAME || 'cfs_platform',
  username: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || '',
  logging: process.env.NODE_ENV === 'development' ? console.log : false
};

4. INDEX BARREL EXPORTS:
Create packages/database/src/index.js:
const sequelize = require('./connection');
const Customer = require('./models/Customer')(sequelize);
const Donation = require('./models/Donation')(sequelize);

// Set up associations
Customer.hasMany(Donation);
Donation.belongsTo(Customer);

module.exports = {
  sequelize,
  Customer,
  Donation
};

5. PACKAGE.JSON:
{
  "name": "@cfs-platform/database",
  "version": "1.0.0",
  "main": "src/index.js",
  "dependencies": {
    "sequelize": "^6.35.0",
    "mysql2": "^3.6.0"
  }
}

6. README.MD:
Document:
- Supported database models
- Basic initialization patterns
- Integration code examples
- Active environment variable configuration keys

7. REFACTORING in apps/zuwendung/:
Replace all local DB imports with imports referencing the shared database workspace package:

Before:
import Customer from './models/Customer';

After:
import { Customer } from '@cfs-platform/database';

Remove the extracted local database files from apps/zuwendung/ src tree.

Antigravity Prompt #4b - UI Components Package:

text
Extract reusable UI elements and layouts from apps/zuwendung/ into a shared packages library:

PACKAGE: @cfs-platform/ui-components
TARGET: packages/ui-components/src/components/

TASKS:

1. IDENTIFY REUSABLE ELEMENTS:
Locate all shared UI structures inside apps/zuwendung/src/components/:
- Button
- Input
- Select
- Table
- Modal
- Card
- etc.

2. EXTRACT ELEMENT SCHEMAS:
For each element, define a clean folder structure:

packages/ui-components/src/components/Button/
├── Button.jsx
├── Button.css
└── index.js

Button.jsx:
import React from 'react';
import './Button.css';

const Button = ({
  children,
  variant = 'primary',
  size = 'md',
  onClick,
  disabled = false,
  ...props
}) => {
  return (
    <button
      className={`btn btn--${variant} btn--${size}`}
      onClick={onClick}
      disabled={disabled}
      {...props}
    >
      {children}
    </button>
  );
};

export default Button;

Button.css (referencing unified CSS design tokens):
@import '../../styles/variables.css';

.btn {
  font-family: var(--font-family-primary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-medium);
  padding: var(--spacing-sm) var(--spacing-md);
  border: none;
  border-radius: var(--border-radius-md);
  cursor: pointer;
  transition: all var(--transition-fast);
}

.btn--primary {
  background-color: var(--color-primary);
  color: white;
}

.btn--primary:hover {
  background-color: var(--color-secondary);
}

.btn--secondary {
  background-color: var(--color-background-paper);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-default);
}

.btn--sm {
  font-size: var(--font-size-sm);
  padding: var(--spacing-xs) var(--spacing-sm);
}

.btn--lg {
  font-size: var(--font-size-lg);
  padding: var(--spacing-md) var(--spacing-lg);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

index.js:
export { default } from './Button';

3. BARREL EXPORTS:
Update packages/ui-components/src/index.js to export all components:

// Styles
import './styles/global.css';

// Components
export { default as Button } from './components/Button';
export { default as Input } from './components/Input';
export { default as Select } from './components/Select';
export { default as Table } from './components/Table';
export { default as Modal } from './components/Modal';
export { default as Card } from './components/Card';

// Design Tokens
export { default as designTokens } from './styles/design-tokens.json';

4. RULES:
- Component styles must exclusively resolve via global CSS design token properties.
- Strictly zero hardcoded values for layouts, sizing, padding, colors, or shadows.
- Keep elements highly customizable, responsive, accessible, and robust.

5. REFACTORING in apps/zuwendung/:
Replace all local component references:

Before:
import Button from './components/Button';

After:
import { Button } from '@cfs-platform/ui-components';

Delete the corresponding local files from apps/zuwendung/ src tree.

Antigravity Prompt #4c - Utils Package:

text
Create a shared utilities package workspace:

PACKAGE: @cfs-platform/utils
TARGET: packages/utils/

STRUCTURE:
packages/utils/
├── src/
│   ├── validators.js
│   ├── formatters.js
│   ├── logger.js
│   ├── constants.js
│   └── index.js
├── package.json
└── README.md

TASKS:

1. VALDATION HELPERS:
Create packages/utils/src/validators.js:

export const isValidEmail = (email) => {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return regex.test(email);
};

export const isValidAmount = (amount) => {
  return !isNaN(amount) && parseFloat(amount) > 0;
};

export const isValidDate = (dateString) => {
  const date = new Date(dateString);
  return date instanceof Date && !isNaN(date);
};

export const isValidIBAN = (iban) => {
  const regex = /^[A-Z]{2}\d{2}[A-Z0-9]+$/;
  return regex.test(iban.replace(/\s/g, ''));
};

2. FORMATTING HELPERS:
Create packages/utils/src/formatters.js:

export const formatCurrency = (amount, currency = 'EUR', locale = 'de-DE') => {
  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency
  }).format(amount);
};

export const formatDate = (date, locale = 'de-DE') => {
  return new Intl.DateTimeFormat(locale, {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  }).format(new Date(date));
};

export const formatDateTime = (date, locale = 'de-DE') => {
  return new Intl.DateTimeFormat(locale, {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  }).format(new Date(date));
};

export const truncateText = (text, maxLength = 100) => {
  if (text.length <= maxLength) return text;
  return text.substring(0, maxLength) + '...';
};

3. LOGGING:
Create packages/utils/src/logger.js:

const LOG_LEVELS = {
  ERROR: 'error',
  WARN: 'warn',
  INFO: 'info',
  DEBUG: 'debug'
};

class Logger {
  constructor(context = 'App') {
    this.context = context;
  }

  error(message, ...args) {
    console.error(`[${this.context}] ERROR:`, message, ...args);
  }

  warn(message, ...args) {
    console.warn(`[${this.context}] WARN:`, message, ...args);
  }

  info(message, ...args) {
    console.info(`[${this.context}] INFO:`, message, ...args);
  }

  debug(message, ...args) {
    if (process.env.NODE_ENV === 'development') {
      console.debug(`[${this.context}] DEBUG:`, message, ...args);
    }
  }
}

export default Logger;

4. PLATFORM CONSTANTS:
Create packages/utils/src/constants.js:

export const APP_NAME = 'CFS Platform';
export const APP_VERSION = '1.0.0';

export const DATE_FORMATS = {
  SHORT: 'DD.MM.YYYY',
  LONG: 'DD. MMMM YYYY',
  ISO: 'YYYY-MM-DD'
};

export const FILE_UPLOAD = {
  MAX_SIZE: 10 * 1024 * 1024, // 10MB
  ALLOWED_TYPES: ['application/pdf', 'image/jpeg', 'image/png']
};

export const PAGINATION = {
  DEFAULT_PAGE_SIZE: 20,
  MAX_PAGE_SIZE: 100
};

5. INDEX BARREL EXPORTS:
Create packages/utils/src/index.js:

export * from './validators';
export * from './formatters';
export * from './constants';
export { default as Logger } from './logger';

6. PACKAGE.JSON:
{
  "name": "@cfs-platform/utils",
  "version": "1.0.0",
  "main": "src/index.js"
}

7. README.MD:
Document all available utility methods with code examples.

8. REFACTORING in apps/zuwendung/:
Replace local utility functions:

import { formatCurrency, isValidEmail, Logger } from '@cfs-platform/utils';

Post-Phase 4 - Git Commit:

bash
# Stage new packages
git add packages/

# Stage refactored application imports
git add apps/zuwendung/

# Commit
git commit -m "feat: Extract shared packages (database, ui-components, utils)"

# Push branch to remote
git push origin feature/migrate-zuwendung

Testing:

bash
cd cfs-platform
npm install
cd apps/zuwendung
npm run dev
# ZWB app should operate flawlessly consuming workspaces packages

Checklist:

  • [ ] Database package fully verified
  • [ ] UI components library created and styled using tokens
  • [ ] Utils package complete
  • [ ] ZWB application imports refactored
  • [ ] Dev server compiles and executes ZWB app
  • [ ] Git commit successfully made

Phase 5: Develop Portal App

(Prompts #5a and #5b executed identically, followed by Git commits)

Post-Phase 5 - Git Commit:

bash
# Stage new portal application
git add apps/portal/

# Stage AppShell changes in UI library
git add packages/ui-components/

# Commit
git commit -m "feat: Add portal app with dashboard and AppShell component"

# Push feature branch
git push origin feature/migrate-zuwendung

Merge into Main Branch:

bash
# Switch branch
git checkout main

# Merge feature branch
git merge feature/migrate-zuwendung

# Push changes to GitHub
git push origin main

# Clean up local feature branch
git branch -d feature/migrate-zuwendung

# Clean up remote feature branch
git push origin --delete feature/migrate-zuwendung

Phase 6: Integrate Zuwendung App

(Prompt #6 executed identically)

Post-Phase 6 - Git Commit:

bash
# Switch branch
git checkout -b feature/integrate-appshell

# Stage refactored donation app layout files
git add apps/zuwendung/

# Commit
git commit -m "feat: Integrate AppShell into Zuwendung app"

# Push feature branch
git push -u origin feature/integrate-appshell

# Merge feature branch into main
git checkout main
git merge feature/integrate-appshell
git push origin main

Phase 7: Docker Setup

(Prompt #7 executed identically)

Post-Phase 7 - Git Commit:

bash
# Switch branch
git checkout -b feature/docker-setup

# Stage Docker configuration files
git add docker/
git add apps/*/Dockerfile*

# Commit
git commit -m "feat: Add Docker setup with Nginx reverse proxy"

# Push feature branch
git push -u origin feature/docker-setup

# Merge feature branch into main
git checkout main
git merge feature/docker-setup
git push origin main

Phase 8: Develop New Modules

For each new module workspace app (Mailing, Newsletter):

bash
# Create feature branch
git checkout -b feature/mailing-module

# Build out features using Antigravity prompts...

# Update UI registry
git add packages/ui-components/src/config/modules.json

# Add new application workspace files
git add apps/mailing/

# Adjust Docker orchestration configurations
git add docker/

# Commit
git commit -m "feat: Add mailing module with bulk email functionality"

# Push feature branch
git push -u origin feature/mailing-module

# Open Pull Request and merge into main

Git Workflow Summary

Branching Strategy

main                    # Production (stable releases)
  ├── develop           # Integration and staging (optional)
  ├── feature/xxx       # Feature branches
  ├── bugfix/xxx        # Bug fix branches
  └── hotfix/xxx        # Production emergency patches

Daily Routine Commands

bash
# 1. Fetch latest changes
git checkout main
git pull origin main

# 2. Spawn a dedicated work branch
git checkout -b feature/new-capability

# 3. Code, test, and commit
git add .
git commit -m "feat: brief description"

# 4. Push work branch to origin
git push -u origin feature/new-capability

# 5. Open Pull Request on GitHub
# 6. Perform review and merge into main
# 7. Clean up work branch
git checkout main
git branch -d feature/new-capability

Released under proprietary license.