diff --git a/docs/Analysis.md b/docs/Analysis.md
deleted file mode 100644
index 36ef2cd..0000000
--- a/docs/Analysis.md
+++ /dev/null
@@ -1,600 +0,0 @@
-# POSTERG Migration Analysis: YAML to SQLite
-
-## Executive Summary
-
-This analysis examines the migration of the POSTERG thesis archive system from static YAML files to a SQLite database. The goal is to improve performance, scalability, and usability while maintaining the project's core mission of preserving and sharing masters theses from ERG art school.
-
----
-
-## Current System Architecture
-
-### Repository Structure
-
-The project consists of two interconnected repositories:
-
-1. **posterg-formulaire**: Submission interface
- - PHP-based web form for students to submit thesis metadata
- - Handles file uploads (PDFs, images, videos, ZIP archives)
- - Generates YAML files with unique identifiers
- - Stores uploaded content in structured directories
-
-2. **posterg-website**: Public display interface
- - PHP-based browsing and viewing application
- - Reads YAML files on each request
- - Presents paginated gallery view
- - Individual thesis detail pages with embedded media
-
-### Data Model (Current)
-
-Each thesis entry contains:
-- **auteurice**: Author name
-- **année**: Graduation year
-- **email**: Contact email
-- **titre**: Thesis title
-- **tag**: Array of keywords/tags
-- **promoteurice**: Thesis supervisor(s)
-- **problématique**: Problem statement
-- **description**: Full description/abstract
-- **orientation**: Program/department
-- **ap**: Additional program designation
-- **couverture**: Cover image path
-- **files**: Array of associated file paths
-
-### Storage Structure
-
-```
-data/
-├── yaml/ # Metadata files (13 currently)
-├── content/ # Uploaded thesis files
-│ └── {year}/
-│ └── {author}/
-│ └── [files]
-└── cover/ # Cover images
-```
-
-Current data volume: 69MB
-
----
-
-## Performance Bottlenecks Identified
-
-### Critical Issues
-
-1. **File System Scanning on Every Request**
- - `glob("data/yaml/*.yaml")` scans directory for every page load
- - No caching mechanism
- - Linear time complexity O(n) for file discovery
-
-2. **Complete Dataset Loading**
- - All YAML files parsed on every request
- - Memory consumption scales linearly with dataset size
- - Even pagination requires loading complete dataset
-
-3. **Sorting After Loading**
- - All records loaded into memory before sorting
- - Year-based sorting happens at runtime
- - No pre-computed order
-
-4. **No Query Optimization**
- - Cannot filter at data source
- - No indexes for common access patterns
- - Tag searches would require parsing all files
-
-### Scalability Concerns
-
-With current architecture at 100 theses:
-- 100 file system calls per request
-- 100 YAML parse operations per request
-- Full dataset held in memory for sorting
-
-With projected growth to 1000+ theses:
-- System becomes unusable
-- Memory exhaustion likely
-- Response times in seconds
-
----
-
-## SQLite Migration Benefits
-
-### Performance Improvements
-
-1. **Query Optimization**
- - Direct pagination with LIMIT/OFFSET
- - Index-based lookups (year, author, tags)
- - Sorted results without in-memory processing
- - Query only needed fields
-
-2. **Search Capabilities**
- - Full-text search on titles and descriptions
- - Tag-based filtering with JOIN tables
- - Year range queries
- - Author/supervisor lookups
- - Multi-criteria searches
-
-3. **Caching Potential**
- - Database query results cacheable
- - Prepared statements for repeated queries
- - Connection pooling
-
-### Functional Enhancements
-
-1. **Advanced Filtering**
- - Filter by year, program, supervisor
- - Multi-tag selection
- - Combined criteria (AND/OR logic)
- - Exclusion filters
-
-2. **Statistical Views**
- - Theses per year graphs
- - Most common tags
- - Popular programs/orientations
- - Supervisor contribution counts
-
-3. **Related Content**
- - "Similar theses" based on tags
- - Same supervisor works
- - Year cohort browsing
-
-4. **Data Validation**
- - Schema enforcement
- - Required field validation
- - Foreign key constraints
- - Data type checking
-
----
-
-## Proposed Database Schema
-
-### Core Tables
-
-**theses**
-- id: INTEGER PRIMARY KEY AUTOINCREMENT
-- author: TEXT NOT NULL
-- year: INTEGER NOT NULL
-- email: TEXT
-- title: TEXT NOT NULL
-- supervisor: TEXT
-- problem_statement: TEXT
-- description: TEXT NOT NULL
-- orientation: TEXT
-- additional_program: TEXT
-- cover_image_path: TEXT
-- external_link: TEXT
-- created_at: DATETIME DEFAULT CURRENT_TIMESTAMP
-- updated_at: DATETIME DEFAULT CURRENT_TIMESTAMP
-
-**tags**
-- id: INTEGER PRIMARY KEY AUTOINCREMENT
-- name: TEXT UNIQUE NOT NULL
-
-**thesis_tags** (many-to-many junction)
-- thesis_id: INTEGER FOREIGN KEY → theses(id)
-- tag_id: INTEGER FOREIGN KEY → tags(id)
-- PRIMARY KEY (thesis_id, tag_id)
-
-**files**
-- id: INTEGER PRIMARY KEY AUTOINCREMENT
-- thesis_id: INTEGER FOREIGN KEY → theses(id)
-- file_path: TEXT NOT NULL
-- file_type: TEXT NOT NULL (pdf, image, video, archive)
-- file_size: INTEGER
-- mime_type: TEXT
-- uploaded_at: DATETIME DEFAULT CURRENT_TIMESTAMP
-
-### Indexes for Performance
-
-```sql
-CREATE INDEX idx_theses_year ON theses(year DESC);
-CREATE INDEX idx_theses_author ON theses(author);
-CREATE INDEX idx_theses_orientation ON theses(orientation);
-CREATE INDEX idx_tags_name ON tags(name);
-CREATE INDEX idx_thesis_tags_thesis ON thesis_tags(thesis_id);
-CREATE INDEX idx_thesis_tags_tag ON thesis_tags(tag_id);
-CREATE INDEX idx_files_thesis ON files(thesis_id);
-```
-
-### Full-Text Search
-
-```sql
-CREATE VIRTUAL TABLE theses_fts USING fts5(
- title,
- description,
- problem_statement,
- content=theses,
- content_rowid=id
-);
-```
-
----
-
-## Migration Strategy
-
-### Phase 1: Database Setup
-
-1. Create SQLite database file
-2. Implement schema with all tables
-3. Add indexes and constraints
-4. Set up full-text search tables
-5. Create database access layer (PDO wrapper)
-
-### Phase 2: Data Migration
-
-1. Build migration script to:
- - Read all existing YAML files
- - Parse and validate data
- - Insert into database tables
- - Maintain file path references
- - Create tag associations
- - Generate migration log
-
-2. Verification process:
- - Count validation (YAML count = DB count)
- - Sample data comparison
- - File path integrity check
- - Tag relationship validation
-
-### Phase 3: Application Refactoring
-
-**Formulaire Changes:**
-1. Replace YAML generation with database INSERT
-2. Maintain file storage structure (unchanged)
-3. Add database transaction handling
-4. Implement tag normalization
-5. Add duplicate detection
-
-**Website Changes:**
-1. Replace glob/parse operations with SQL queries
-2. Implement prepared statements for security
-3. Add search functionality
-4. Create filtering UI components
-5. Implement pagination with SQL LIMIT/OFFSET
-
-### Phase 4: Enhanced Features
-
-1. Search interface (full-text + filters)
-2. Tag cloud visualization
-3. Year-based browsing
-4. Statistics dashboard
-5. Related theses suggestions
-6. Advanced filtering controls
-
-### Phase 5: Backward Compatibility
-
-1. Keep YAML export functionality
-2. Generate YAML on thesis update (optional)
-3. Maintain file structure unchanged
-4. Preserve URL patterns
-5. Create database backup mechanism
-
----
-
-## Implementation Considerations
-
-### Data Integrity
-
-1. **Validation Rules**
- - Required fields: author, year, title, description
- - Year range validation (1900-current)
- - Email format validation
- - File path existence verification
-
-2. **Constraint Handling**
- - Unique file paths within thesis
- - Orphan file prevention (foreign keys)
- - Tag name uniqueness (case-insensitive)
-
-3. **Transaction Safety**
- - Atomic thesis creation (metadata + files + tags)
- - Rollback on failure
- - File cleanup on database failure
-
-### Security Improvements
-
-1. **SQL Injection Prevention**
- - PDO prepared statements throughout
- - Never concatenate user input into queries
- - Parameterized queries only
-
-2. **File System Security**
- - Maintain current upload restrictions
- - Database stores sanitized paths only
- - Path traversal prevention
-
-3. **Data Exposure**
- - Email address handling policy
- - Optional field visibility controls
- - Query result limiting
-
-### Performance Optimization
-
-1. **Connection Management**
- - Persistent database connections
- - Connection pooling for concurrent requests
- - Prepared statement caching
-
-2. **Query Optimization**
- - Avoid SELECT * queries
- - Use pagination efficiently
- - Leverage indexes for all searches
- - Cache expensive aggregate queries
-
-3. **File Handling**
- - Database stores paths only (not binary data)
- - File serving remains filesystem-based
- - Consider CDN for static assets
-
-### Maintenance Requirements
-
-1. **Database Maintenance**
- - Regular VACUUM operations for database compaction
- - Backup strategy (daily automated backups)
- - Full-text search index updates
- - Periodic ANALYZE for query optimization
-
-2. **Migration Tools**
- - YAML export functionality for portability
- - Database schema versioning
- - Update scripts for schema evolution
-
-3. **Monitoring**
- - Query performance logging
- - Slow query identification
- - Database size monitoring
- - Error logging and alerting
-
----
-
-## Usability Enhancements
-
-### New User Features
-
-1. **Search Functionality**
- - Free-text search across titles and descriptions
- - Tag-based filtering (AND/OR logic)
- - Year range selection
- - Program/orientation filters
- - Supervisor search
- - Combined multi-criteria searches
-
-2. **Navigation Improvements**
- - Alphabetical author index
- - Chronological timeline view
- - Tag cloud with frequency indicators
- - "Browse by" menus (year, program, supervisor)
-
-3. **Discovery Features**
- - "Similar theses" recommendations
- - Tag-based related content
- - Same supervisor works
- - Recent additions feed
- - Random thesis discovery
-
-4. **Submission Experience**
- - Duplicate detection warnings
- - Tag suggestions from existing tags
- - Form validation with helpful messages
- - Upload progress indicators
- - Preview before submission
-
-### Administrative Features
-
-1. **Content Management**
- - Edit thesis metadata post-submission
- - Bulk tag operations
- - Merge duplicate tags
- - Thesis approval workflow
- - Content moderation tools
-
-2. **Analytics Dashboard**
- - Total theses count
- - Submissions per year graph
- - Most popular tags
- - Program distribution
- - File type statistics
- - Storage usage metrics
-
-3. **Data Export**
- - CSV export for analysis
- - JSON API for integrations
- - YAML backup generation
- - Bulk download capabilities
-
----
-
-## Performance Projections
-
-### Current System (YAML)
-- 13 theses: ~50ms response time
-- 100 theses: ~400ms estimated
-- 1000 theses: ~4000ms estimated (unusable)
-- Memory: Linear growth O(n)
-
-### SQLite System (Projected)
-- 13 theses: ~5ms response time
-- 100 theses: ~8ms response time
-- 1000 theses: ~15ms response time
-- 10,000 theses: ~30ms response time (with proper indexes)
-- Memory: Constant per request O(page_size)
-
-### Scalability Metrics
-
-Current bottleneck: 100 theses before major performance issues
-Post-migration capacity: 10,000+ theses with acceptable performance
-
----
-
-## Risk Analysis
-
-### Migration Risks
-
-1. **Data Loss**
- - Mitigation: Comprehensive backup before migration
- - Verification: Automated comparison scripts
- - Rollback: Keep YAML files as archive
-
-2. **Downtime**
- - Mitigation: Migrate offline database first
- - Testing: Staging environment validation
- - Deployment: Blue-green deployment strategy
-
-3. **Bug Introduction**
- - Mitigation: Extensive testing suite
- - Validation: User acceptance testing
- - Monitoring: Error tracking system
-
-### Operational Risks
-
-1. **Database Corruption**
- - Mitigation: Regular automated backups
- - Recovery: Point-in-time restore capability
- - Prevention: Write-ahead logging enabled
-
-2. **Concurrency Issues**
- - Mitigation: SQLite WAL mode for better concurrency
- - Testing: Load testing before production
- - Monitoring: Lock timeout tracking
-
-3. **Schema Evolution**
- - Mitigation: Migration script versioning
- - Documentation: Schema change log
- - Testing: Migration testing on copies
-
----
-
-## Timeline Estimation
-
-### Development Phases
-
-**Phase 1: Database Design & Setup** (1 week)
-- Schema finalization
-- Database creation scripts
-- Index design
-- Testing framework setup
-
-**Phase 2: Migration Script Development** (1 week)
-- YAML parser improvements
-- Database insertion logic
-- Validation and verification
-- Error handling and logging
-
-**Phase 3: Application Refactoring** (2 weeks)
-- Database access layer
-- Query optimization
-- Form submission updates
-- Display page refactoring
-- URL structure preservation
-
-**Phase 4: Feature Enhancement** (2 weeks)
-- Search implementation
-- Filter UI components
-- Statistics dashboard
-- Related content logic
-- Tag management interface
-
-**Phase 5: Testing & Deployment** (1 week)
-- Integration testing
-- Performance testing
-- User acceptance testing
-- Staging deployment
-- Production migration
-
-**Total Estimated Timeline: 7 weeks**
-
----
-
-## Success Criteria
-
-### Technical Metrics
-
-1. **Performance**
- - Page load time < 100ms for gallery view
- - Search response time < 200ms
- - Support 1000+ theses without degradation
-
-2. **Reliability**
- - 99.9% uptime
- - Zero data loss during migration
- - All URLs preserved or redirected
-
-3. **Functionality**
- - All existing features maintained
- - Search accuracy > 95%
- - Filter combinations work correctly
-
-### User Experience Metrics
-
-1. **Usability**
- - Submission form completion rate > 90%
- - Search usage > 30% of visits
- - Average session duration increase
-
-2. **Content Discovery**
- - Pages per session increase
- - Tag-based navigation usage
- - Related thesis click-through rate
-
-3. **Satisfaction**
- - User feedback surveys positive
- - Error rate < 1%
- - Form abandonment rate decrease
-
----
-
-## Post-Migration Roadmap
-
-### Immediate Next Steps
-
-1. Monitor performance metrics
-2. Gather user feedback
-3. Address any bugs or issues
-4. Optimize slow queries
-5. Document new workflows
-
-### Future Enhancements
-
-1. **API Development**
- - RESTful API for external access
- - JSON endpoints for integrations
- - Authentication for write operations
-
-2. **Advanced Features**
- - Citation generation tools
- - DOI/persistent identifier integration
- - Version control for thesis updates
- - Collaborative annotations
-
-3. **Integration Opportunities**
- - Library catalog integration (BAIU)
- - ERG website integration
- - Academic search engines
- - Social media sharing
-
-4. **Archival Features**
- - Long-term preservation planning
- - Format migration for obsolete files
- - Redundant backup locations
- - Metadata standards compliance (Dublin Core)
-
----
-
-## Conclusion
-
-The migration from YAML static files to SQLite database represents a critical infrastructure improvement for the POSTERG project. The current system, while functional for the initial prototype phase, faces severe scalability limitations that will prevent the project from fulfilling its mission of comprehensive thesis archival and accessibility.
-
-### Key Benefits Summary
-
-1. **Performance**: 10-50x faster page loads, sustainable with 1000+ theses
-2. **Functionality**: Full-text search, advanced filtering, statistics, related content
-3. **Maintainability**: Structured data, validation, easier debugging and updates
-4. **User Experience**: Better discovery, faster browsing, richer information access
-5. **Sustainability**: Scalable architecture supporting long-term growth
-
-### Recommendation
-
-Proceed with SQLite migration as outlined in this analysis. The investment in migration and refactoring will pay immediate dividends in performance and enable the feature enhancements that will make POSTERG a truly valuable resource for the ERG community. The proposed timeline of 7 weeks is realistic and provides adequate time for thorough testing and quality assurance.
-
-The mission of preserving and democratizing access to ERG theses—challenging the traditional library model that prioritizes grades over accessibility—deserves a technical foundation that can grow with the archive. This migration provides that foundation.
-
----
-
-*This analysis prepared for the POSTERG project migration initiative, January 2026.*
diff --git a/docs/COMPLETE_DEPLOYMENT_GUIDE.md b/docs/COMPLETE_DEPLOYMENT_GUIDE.md
deleted file mode 100644
index 8e5198f..0000000
--- a/docs/COMPLETE_DEPLOYMENT_GUIDE.md
+++ /dev/null
@@ -1,400 +0,0 @@
-# Complete Deployment Guide - New Structure
-
-## Overview
-
-This guide walks you through deploying the new secure directory structure:
-- **Old:** `/var/www/html/` (everything exposed)
-- **New:** `/var/www/posterg/` with `public/` subdirectory (only public/ exposed)
-
-## Step-by-Step Deployment
-
-### ⚠️ IMPORTANT: Do NOT delete /var/www/html/ yet!
-
-Keep it as a backup until you confirm the new structure works.
-
----
-
-### Step 1: Setup Server Directory (Manual - One Time)
-
-SSH to server and create the new directory:
-
-```bash
-ssh posterg
-
-# Backup current site
-sudo cp -r /var/www/html /var/www/html.backup
-
-# Create new directory
-sudo mkdir -p /var/www/posterg
-
-# Set ownership (www-data = web server user)
-sudo chown www-data:posterg /var/www/posterg
-
-# Set permissions
-sudo chmod 775 /var/www/posterg
-
-# Verify
-ls -ld /var/www/posterg
-# Should show: drwxrwxr-x 2 www-data posterg ...
-
-# Exit server
-exit
-```
-
----
-
-### Step 2: Deploy Application Files
-
-From your local machine:
-
-```bash
-just deploy
-```
-
-This will:
-- Upload all files to `/var/www/posterg/`
-- Exclude unnecessary files (tests, docs, etc.)
-- Set initial ownership to `www-data:posterg`
-
-You should see:
-```
-sending incremental file list
-public/index.php
-public/search.php
-public/memoire.php
-...
-```
-
----
-
-### Step 3: Deploy Nginx Configuration
-
-```bash
-just deploy-nginx
-```
-
-This will:
-1. Check that nginx config has correct DocumentRoot (`/var/www/posterg/public`)
-2. Upload `posterg.conf` to `/tmp/` on server
-3. Upload `deploy-production-new.sh` to `/tmp/` on server
-
-Expected output:
-```
-✅ nginx config looks correct
-✅ Files uploaded to /tmp/ on server
-```
-
----
-
-### Step 4: Apply Nginx Configuration on Server
-
-SSH to server and run the deployment script:
-
-```bash
-ssh posterg
-sudo bash /tmp/deploy-production.sh
-```
-
-The script will:
-1. Fix file permissions on `/var/www/posterg/`
-2. Backup existing nginx config
-3. Install new nginx config
-4. Test nginx configuration
-5. Show you the reload command
-
-Expected output:
-```
-🚀 Post-ERG Production Deployment (NEW STRUCTURE)
-==================================================
-
-📋 Step 1: Fixing file permissions...
-✓ Changed ownership to www-data:posterg
-✓ Set directory permissions to 755
-✓ Set file permissions to 644
-✓ Made database directory group-writable (775)
-✓ Fixed database file permissions (660)
-
-📋 Step 2: Deploying nginx configuration...
-✓ Backed up existing config
-✓ Installed new nginx config
-
-📋 Step 3: Testing nginx configuration...
-✓ Nginx configuration is valid
-
-📋 Step 4: Summary...
-✓ Permissions fixed
-✓ Nginx config installed
-✓ Configuration validated
-
-Ready to reload nginx!
-
-Run: sudo systemctl reload nginx
-```
-
----
-
-### Step 5: Reload Nginx
-
-Still on the server:
-
-```bash
-sudo systemctl reload nginx
-```
-
-If successful, you'll see no output (which is good!).
-
-Check status:
-```bash
-sudo systemctl status nginx
-# Should show "active (running)"
-```
-
-Exit server:
-```bash
-exit
-```
-
----
-
-### Step 6: Verify Deployment
-
-From your local machine:
-
-```bash
-just server-status
-```
-
-Expected output:
-```
-🔍 Server Status
-================
-✓ Nginx running
-✓ PHP-FPM running
-
-Site check:
- • Public: 200 ✓
- • Admin: 200 ✓
-```
-
----
-
-### Step 7: Security Verification
-
-Test these URLs in your browser or with curl:
-
-```bash
-# Should work (200 OK):
-curl -I https://posterg.erg.be/
-curl -I https://posterg.erg.be/admin/
-
-# Should be 404 (SECURITY - private files):
-curl -I https://posterg.erg.be/storage/test.db
-curl -I https://posterg.erg.be/config/bootstrap.php
-curl -I https://posterg.erg.be/includes/header.php
-curl -I https://posterg.erg.be/lib/Database.php
-```
-
-**All private files must return 404!** If they don't, nginx is not configured correctly.
-
----
-
-### Step 8: Deploy Database (If Needed)
-
-If you need to update the database:
-
-```bash
-just deploy-database
-```
-
-This will warn you before overwriting.
-
----
-
-### Step 9: Test Thoroughly
-
-- [ ] Visit https://posterg.erg.be/
-- [ ] Browse thesis list
-- [ ] Open a thesis detail page
-- [ ] Try search functionality
-- [ ] Access admin panel (should require login)
-- [ ] Verify private files return 404
-
----
-
-### Step 10: Keep Backup for a While
-
-**Do NOT delete `/var/www/html/` immediately!**
-
-Keep it for a few days to ensure everything works. If you need to rollback:
-
-```bash
-ssh posterg
-sudo nano /etc/nginx/sites-available/posterg
-# Change: root /var/www/posterg/public;
-# Back to: root /var/www/html;
-sudo systemctl reload nginx
-```
-
-Your old site will work immediately.
-
----
-
-## After Confirming Everything Works
-
-A few days later, once you're confident:
-
-```bash
-ssh posterg
-sudo rm -rf /var/www/html.backup
-sudo rm -rf /var/www/html
-```
-
----
-
-## What Changed?
-
-### Directory Structure
-
-```
-OLD: NEW:
-/var/www/html/ /var/www/posterg/
-├── index.php ├── public/ ← DocumentRoot
-├── search.php │ ├── index.php
-├── admin/ │ ├── search.php
-├── assets/ │ ├── memoire.php
-├── database/ ❌ exposed │ ├── admin/
-├── lib/ ❌ exposed │ └── assets/
-└── ... ├── includes/ ✅ private
- ├── config/ ✅ private
- ├── database/ ✅ private
- └── lib/ ✅ private
-```
-
-### Nginx Configuration
-
-```nginx
-# OLD
-root /var/www/html;
-location ^~ /formulaire/ { ... }
-
-# NEW
-root /var/www/posterg/public;
-location ^~ /admin/ { ... }
-```
-
-### Security Impact
-
-| Resource | Old | New |
-|----------|-----|-----|
-| Database | ❌ Accessible if nginx misconfigured | ✅ Physically outside web root |
-| Config files | ❌ One deny rule away | ✅ Physically private |
-| Source code | ❌ Exposed | ✅ Physically private |
-| Admin panel | /formulaire/ | /admin/ |
-
----
-
-## Troubleshooting
-
-### Site returns 404 for everything
-
-**Cause:** Nginx still pointing to old location or wrong DocumentRoot
-
-**Fix:**
-```bash
-ssh posterg
-sudo cat /etc/nginx/sites-available/posterg | grep "root "
-# Should show: root /var/www/posterg/public;
-```
-
-If wrong:
-```bash
-sudo nano /etc/nginx/sites-available/posterg
-# Fix the root directive
-sudo systemctl reload nginx
-```
-
-### Database errors
-
-**Cause:** Wrong permissions on database file
-
-**Fix:**
-```bash
-ssh posterg
-sudo chown www-data:posterg /var/www/posterg/storage/test.db
-sudo chmod 660 /var/www/posterg/storage/test.db
-```
-
-### Admin upload errors
-
-**Cause:** Upload directories not writable
-
-**Fix:**
-```bash
-ssh posterg
-sudo chmod 775 /var/www/posterg/public/admin/data
-sudo find /var/www/posterg/public/admin/data -type d -exec chmod 775 {} \;
-```
-
-### Private files still accessible
-
-**Cause:** Nginx serving from wrong directory
-
-**Fix:** Verify nginx DocumentRoot and reload
-
----
-
-## Rollback Procedure
-
-If you need to go back to the old structure:
-
-```bash
-# 1. SSH to server
-ssh posterg
-
-# 2. Restore old nginx config
-sudo nano /etc/nginx/sites-available/posterg
-# Change: root /var/www/posterg/public;
-# To: root /var/www/html;
-# Change: location ^~ /admin/
-# To: location ^~ /formulaire/
-
-# 3. Reload nginx
-sudo systemctl reload nginx
-
-# 4. Verify
-curl -I https://posterg.erg.be/
-```
-
-Your old site should work immediately (as long as you didn't delete `/var/www/html/`).
-
----
-
-## Quick Reference
-
-| Task | Command |
-|------|---------|
-| Deploy files | `just deploy` |
-| Deploy nginx | `just deploy-nginx` |
-| Deploy database | `just deploy-database` |
-| Check status | `just server-status` |
-| View logs | `just server-logs` |
-
----
-
-## Success Checklist
-
-- [ ] `/var/www/posterg/` created with correct permissions
-- [ ] Files deployed with `just deploy`
-- [ ] Nginx config deployed with `just deploy-nginx`
-- [ ] Permissions fixed with `deploy-production.sh`
-- [ ] Nginx reloaded successfully
-- [ ] Site accessible at https://posterg.erg.be/
-- [ ] Admin accessible at https://posterg.erg.be/admin/
-- [ ] Private files return 404 (security verified)
-- [ ] Database working (can view theses)
-- [ ] Search working
-- [ ] Old `/var/www/html/` kept as backup
-
----
-
-**After deployment, your site will be significantly more secure!** 🔒
diff --git a/docs/Context.md b/docs/Context.md
deleted file mode 100644
index 541c14b..0000000
--- a/docs/Context.md
+++ /dev/null
@@ -1,463 +0,0 @@
-
-
- 1 Mémoire POSTERG, a life after erg
-
-Mémoire POSTERG, a life after erg
-Un centre de partage et diffusion...
-
-Théo Hennequin — www.theohennequin.com
-
-Théophile Gervreau-Mercier — tgm.happyngreen.fr
-
-Olivia Marly — oli98marly@gmail.com
-
- Site - Index
-
- Partager son mémoire
-
- À propos.html
-
- Contact.html
-
- visuel interface
-
- visuel interface
-
- visuel interface
-
- Visuel interface
-
-_______________________________________________________________________
-NOTRE SITE WEB :
-
-http://work.designnumerique.be/2022-2023/DN-Posterg/
-
-PAD DE RECHERCHE : https://pads.erg.be/p/DN-pcollectif-edition-serveur
-
-GIT sur terminal pour codeberg : https://designnumerique.be/wiki/Cheatsheet_Git
-
-XML pour hébergement : http://codedrops.net/xml-collection-object/
-
-_______________________________________________________________________
-SCENARIO / EXPLICATION / INTENTION
-
-Nous sommes un groupe d'étudiant·e·s en design numérique avec projet concernant les mémoires de l'année passée qui demande votre aide !
-
-Quand est-il des mémoires après notre master ? Quelle est la visibilité de notre travail après notre départ de l'ERG ? Certains mémoires finissent à la bibliothèque exposés, mais lesquels et pourquoi ? Actuellement, la bibliothèque (BAUI) sert de lieux d'archives (collection de documents anciens, classés à des fins historiques ; lieu où les archives sont conservées) des mémoires pour l'erg, st-Luc et UCL mais pourquoi sont-ils si peu à être exposés ?
-
-Actuellement, les mémoires sélectionnés sont ceux avec une grande distinction (16/20). Cette note obtenue dépend de la cotation de lecture de mémoire et sa défense.
-
-Mais pourquoi cette moyenne de 14/20 ? Et où finissent les autres mémoires ?
-
-En l'occurrence, la bibliothèque n'est pas un lieu de diffusion et de monstration " juste ", car les mémoires dépendent de la note attribuée en fin de Master et de la place disponible dans les étagères ; sans parler de l'état déplorable de certains mémoires due aux conditions de stockages : couverture plastifiée, stickers, etc - nous travaillons un visuel qui finalement sera " dégradé " lors de son exposition à la bibliothèque, si exposé. De plus, les mémoires sont visible en bibliothèque de manière tangible (style édition).
-
-Qu'en t-il des formats numérique, audio ou vidéo ? De fait, notre recherche se pencherait sur un dispositif de partage/diffusion plus adéquat et en phase avec la multitude de format et forme de monstration plus contemporain.
-
-Notre lieu d'archive/exposition prendrait la forme d'un site web, idéalement en ligne (ou en local en fonction du RE - propriété intellectuelle et droit d'auteur ?). Il contiendrait tout types de mémoire ainsi qu'une interrogation autour de sa licence et sa notion de partage. En parallèle, nous donnerons quelques conseils et bon plans pour : "comment licencier son mémoire : pour protéger ses valeurs et notions de partage s'il-y-a" . Dans un premier temps, nous allons collecter un maximum de mémoires et tenter de recontacter leur auteurice pour échanger avec eux et obtenir des pdf, vidéos, photos. Dans un second temps, nous trouverons un relais pour les futures étudiant.e.s et organiseront un formulaire qui publiera automatiquement les mémoires sur notre site.
-
-_______________________________________________________________________
-PERSONNES à CONTACTER DANS LE CADRE DE LA RECHERCHE :
-
- BAIU : laurent.leprince@uclouvain.be (nouveaux mémoires, et/ou anciens format vidéos/audio/site web)
-
- BAIU : laurent.leprince@uclouvain.be
-
- Marie Lécrivain : lecrivainmarie@gmail.com fddl
-
- Loraine Furter : info@lorainefurter.net fddl
-
- Brigitte Ledune : Avoir les mémoires de l'année passée et la liste des étudiant·es
-
- Rideaux de perles : Collaboration pour le scan des mémoires.
-
-_______________________________________________________________________
-DESIGN DE L'INTERFACE SUR PENPOT
-
-https://design.penpot.app/#/workspace/036dc80b-fe30-8148-8001-b90bac520952/840175e6-8ff7-812c-8001-b90bf153f05c?page-id=840175e6-8ff7-812c-8001-b90bf153f05d&layout=assets
-
-_______________________________________________________________________
-INSPIRATIONS
-
-https://www.instagram.com/p/COP6ycahU7G/
-
-https://www.instagram.com/p/CJWVlO1Hnso/
-
-Projets diplomants st-luc
-
-https://www.instagram.com/ephemeride.fun/
-
-Projet étudiant (Nancy), partage de jury (accrochage, exposition) de diplôme en design & art
-
-http://fdddl.be/#
-
-Fonds de documentation et de lecture de l'erg, éditions print issus de dons >>>> Fondatrice : Marie Lécrivain !!
-
-https://www.memo-dg.fr/
-
-Plateforme de partage de DNSEP (diplome national supérieur d'expression plastique) en design graphique, France
-
-_______________________________________________________________________
-Possibilité de Projets
-
-- travail sur les mémoires de l'erg,
-
-- comment mettre sous licence
-
-- comment on les publier/diffuser et rendre public
-
-- une vie après la défense de mémoire, laisser une trace, les faire parler, un dialogue, ...
-
-TITRE DE NOTRE STRUCTURE EDITORIALE????
-
-- MEMOIRE POST-ERG
-
-- A LIFE AFTER ERG
-
-- INTO THE WILD x)
-
-- ERG - INTO THE WILD ?
-
-- LICENCES SURVIVAL PACK - ERG MEMOIRE
-
-__________________________________________________________________
-REFLEXION
-
-> concevoir, construire et mettre en action une "structure de publication" numérique (rendre accessible, de rendre public (publier) et de diffuser un certain contenu consultable au moins en partie sur écran)
-
-> Nous penserons un·e serveur·rice comme une structure éditoriale :
-
-> espace de structure éditoriale : un SSG (structure de dossier avec templates et il insère le contenu qui est souvent en markdown) + GIT + CODEBERG PAGES
-
-https://codeberg.org/Pontoporeia/pages
-
-> à qui s'adresse-t-il >>> à l'ERG et ses alentours/admirateur.ices
-
-> sur quels modèles s'appuie-t-il ? Site web généré avec un SSG, un site qui contient nos revues/numéros avec échange de l'auteurice sur le mémoire et sa licence choisies. Il y'aura également un point de téléchargement du mémoire (texte, audio, vidéo, pad, html, ...)
-
-> en quoi publier est-il un acte politique qui interroge aussi les lieux de diffusion ? Les mémoires finissent à la bibliothèque exposé (si bien jugé ou malheureusement dans les caves de la bibli.......). Actuellement, la bibliothèque n'est pas un lieu de diffusion " juste " car les mémoires dépendent d'une note et de la place disponible dans les étagères... c'est n'est pas le bon dispositif de partage. De plus, les mémoires sont en bibliothèque de manière tangible (style édition) mais qu'en t-il des formats de mémoire audio ou vidéo ? Un site serait accessible pour tout le monde et n'importe quand, de plus il contiendrait tout types de mémoire ainsi qu'une interrogation autour de sa licence et comment licencier son mémoire pour protéger ses valeurs et notions de partage s'il y'a.
-
-> quels contenus? Pour les étudiant.e.s en M1/M2, nous vous proposons de penser à des contenus liés à vos recherches; entretiens, collections d'images, articles trouvés, articles commandités, journal de bord, etc. Ces contenus peuvent être ceux d'autres personnes que vous, la particularité d'un éditeur·ice c'est qu'il·elle est aussi un·e curateur·rice de contenu.
-
-> quelle fréquence de publication? Est-ce que le contenu sera d'abord rassemblé puis publié à intervalles réguliers, à la manière d'une revue? Est-ce qu'il s'agira plutôt d'une publication "en continu" au sein de laquelle le contenu est ajouté progressivement à mesure qu'il est produit, à la manière d'un blog? Progressivement en fonction du contenue et des échange avec les créateur.rices des mémoires
-
-> quel contexte de diffusion? Est-ce que cette structure est accessible globalement sur le web ou plutôt localement, dans un ou des lieux/espaces précis? GLOBALEMENT SUR LE WEB
-
-> quel.le(s) acteur.ice(s) machines? Quelles seront les machines qui interviendront au sein de cette structure, avec quels logiciels, quels protocoles?
-PROTOCOLE :
-
-mettre à disposition le mémoire (photo, scan, lien video, pdf reader)
-
-email ? échange avec l'auteurice.
-
-- le mémoire est-il édité ?
-
-- quelles sont les licences utilisées ?
-
-- pourquoi ce choix ?
-
-
-> quels canaux de communication? Affiches (affichées où et quand)? Réseaux sociaux (lesquels et quand)?
-
-- Un visuel/flyer pour ERG mail (communication de l'ERG en fin d'année et rendu mémoire)
-
-
-__________________________________________________________________
-RÈGLEMENT DE L'ÉCOLE
-
-19.2 Propriété intellectuelle et droits d’auteur De l’inscription de l’étudiant à l’ESA Saint-Luc Bruxelles découle que l’établissement est considéré comme coproducteur des travaux réalisés par l’étudiant dans le cadre de sa formation. Ceci concerne l’ensemble des formes de production et de supports, matériels ou dématérialisés et les travaux individuels aussi bien que les travaux de groupe.
-
-Ceci induit un partage des droits d’auteur entre l’étudiant et l’école et implique :
-
-- pour l’étudiant : de mentionner l’année de création et le nom de l’école (ESA Saint-Luc Bruxelles) lorsqu’il utilisera ou diffusera ces travaux ;
-
-- pour l’ESA Saint-Luc Bruxelles : de mentionner le nom de l’étudiant et l’année de création des travaux qu’elle souhaiterait diffuser, à des fins pédagogiques, artistiques ou promotionnelles uniquement, ce durant toute la durée de protection de ces travaux par le droit d’auteur. En aucun cas, l’école n’est autorisée à vendre les travaux produits par un étudiant, ni à percevoir aucun droit lié à leur utilisation ou leur diffusion par des tiers.
-
-19.2.1 Quandl’étudiantremporteunprixenespècedanslecadred’unconcoursauquellecursusdanslequel il est inscrit a participé avec le suivi d’un/de professeur(s), 50 % du montant de ce prix sera versé sur le compte de l’option, l’autre moitié sera versée sur le compte de l’étudiant.
-
-_____________________________________________________________________________
-Ce travail éditorial autour des mémoires et leur diffusion est né d'une recherche concernant les licences sur les mémoires et leur placement à la bibliothèque voire DISPARITION...
-Les licences libres - MEMOIRES ERG, Un rapport de pouvoir sur les valeurs et la diffusion nos travaux
-
-Ce travail éditorial de 2021-2022 est né d'une recherche menée par :
-
-- Defez Aurélie
-
-- Gervreau-Mercier Théophile
-
-- Debaene Justine
-
-- Troadec Marie
-
-- Marly Olivia
-
-- Goldberg Jacquemain Elodie
-
-Il permet de mieux s’informer sur le libre et sert également de guide aux étudiants qui souhaiteraient trouver des alternatives libre de création dans le numérique et dans la rédaction/mise sous licence de leur futur mémoire. Ces licences renversent le rapport de pouvoir habituel dans les écoles, ils seront maître.sse de la liberté d’utilisation, copie, étude et distribution de leurs travaux.
-Open Source vs Licences libres
-
-Parfois, les personnes qui découvrent le sujet imaginent qu'il s'agit de types de logiciels distincts, les uns sous licence libre, les autres sous licence open source ; sauf que toutes les licences libres (reconnues par la FSF) sont aussi open source (reconnues par l'Open Source Initiative) et vice versa, à quelques exceptions près. Puis, ces personnes s'imaginent qu'il s'agit d'une différence dans les méthodes de développement, ce qui est aussi faux. Ensuite, elles diront par exemple que l'open source est « libéral » quand le libre est « antilibéral », ou de façon plus parlante encore, que l'open source est de droite quand le libre est de gauche.
-
-En tentant d'illustrer la distinction entre « le libre » et « l'open source », on ne fait que redistribuer des oppositions idéologiques qui existent en dehors. On a en partie raison, car ces oppositions sont bien au coeur des projets de société très éloignés d'ESR et de RMS. Mais on a aussi tort, car en faisant cela, on donne l'impression de mouvements qui proposeraient réellement deux projets de société bien définis. Ceux qui militent pour le logiciel libre n'adhèrent pas nécessairement au projet de société de RMS, pas plus que ceux qui défendent l'open source n'adhèrent au projet de société d'ESR. Il y a une chose qu'ESR et RMS ont en commun, c'est la croyance dans le fait qu'il faut défendre la liberté individuelle des utilisateurs, et lutter contre l'asymétrie de droits entre les développeurs et les utilisateurs. À partir de ce principe central peuvent se déployer des projets de société très variés. Pendant des années, le mouvement du Libre s'est opposé de manière frontale au mouvement Open source. Même si elles proviennent de deux approches différentes, les deux définitions sont équivalentes.
-
-À la base les licences Open source ont été crées par l’Open Source Initiative (OSI), la suite à des divergences philosophiques avec la Free Software Fundation (FSF) promouvant, quant à elle, les licences libres. L’OSI a créé une « Open Source Definition » (OSD) décrivant les 10 conditions requises pour qu’une licence appliquée à un logiciel soit considérée comme Open source et accréditée. Globalement, les logiciels répondant aux 10 critères pour être Open source selon la définition de l’OSI accordent également les 4 libertés fondamentales définissant un logiciel libre selon la FSF, et réciproquement. Pour éviter les débats entre Free software, pour désigner les logiciels sous licence libre au sens de la FSF, et Open source software, pour désigner les logiciels sous licences Open source au sens de l’OSI, on voit souvent utilisé le terme de FOSS (Free and Open source Software) ou FLOSS (Free/Libre and Open source Software), on peut également parler de licences FLOS (Free/Libre and Open Source).
-Les différentes licences
-
-Description technique :
-
-Une licence, qui peut aussi être appelée contrat de licence ou licence d’exploitation, est un élément qui concerne le droit de propriété intellectuelle et qui encadre l’utilisation et la diffusion d’un produit. Le type de licence choisi par le propriétaire définit les conditions d’utilisation et de partage pour l’utilisateur, qui est tenu de les respecter.
-
-Il existe différents types de licences : les licences propriétaires, qui n’autorisent qu’un usage privé de l’oeuvre par l’acquéreur légitime, et les licences ouvertes ou licences libres, qui elles-mêmes englobent des sous-catégories de licences libres.
-
-Les licences libres accordent, selon leurs types, tout ou une partie des libertés d’utiliser l’oeuvre. Ces libertés sont la liberté d’utilisation privée, la liberté d'étudier le code, la liberté de redistribution et la liberté de création dérivée.
-
-Dans les licences libres, on retrouve d’abord les licences permissives, définies comme « non-copyleft », qui ne contraignent l’utilisateur qu’à la seule obligation d’attribuer les portions de code sous licence à leurs développeurs d’origine, que ce soit dans le code qu’ils ont développé à partir de celui-ci ou dans leur documentation.
-
-On retrouve dans cette catégorie la licence MIT, la licence BSD ou encore la licence Apache, ainsi que la licence Creative Commons BY. La licence MIT est une licence de logiciel libre ou open source qui provient du MIT College et qui date des années 80. Elle donne le droit illimité d’utiliser, de copier, de modifier, de publier, de distribuer, de vendre et d’incorporer le code sous licence dans une autre licence. La seule obligation est de mettre la notice de licence et de copyright dans toutes les copies.
-
-La licence BSD pour Berkeley Software Distribution est aussi une licence libre utilisée pour la distribution de logiciels. C’est une des moins restrictives, mais qui permet de protéger les auteurs par rapport à l’inscription de leur nom dans les produits dérivés et qui les décharge de la responsabilité d’éventuels problèmes lors de l’utilisation du code.
-
-La licence Apache est une autre licence de logiciel open source qui autorise la modification et la distribution du code que ce soit sous forme libre, propriétaire, gratuite ou commerciale, en n’obligeant seulement à fournir une copie de la licence et la notice avec le code source et d’indiquer clairement le nom du développeur d’origine et que les fichiers ont été modifiés.
-
-La licence Creative Commons BY, ou attribution en français, permet d’utiliser librement l’œuvre à condition de l’attribuer à l’auteur en citant son nom. A part les licences permissives, on retrouve aussi dans les licences libres les licences appelées réciproques, ou « copyleft », qui impliquent une obligation de réciprocité, ce qui signifie que les oeuvres dérivées doivent être distribuées sous la même licence obligatoirement. On retrouve dans cette catégorie la licence GNU GPL, la licence Art Libre, la licence OFL ou la licence Creative Commons BY-SA.
-
-La licence GNU GPL ou licence publique générale GNU fixe les conditions légales de distribution de logiciels libres. C’est la première licence libre créée par la FSF. C'est la licence de logiciel libre la plus utilisée. Elle garantie la liberté d’utiliser le logiciel pour n’importe quel usage, l’accès au codes sources, la liberté de redistribuer des copies, et que les versions modifiées seront diffusées avec les mêmes libertés.
-
-La licence Art Libre est une licence qui s’applique à la création artistique. Elle autorise à copier, transformer ou diffuser une oeuvre librement, dans une visée commerciale ou non, à la seule condition qu’il soit toujours possible d’accéder à l’oeuvre originale.
-
-La licence OFL ou SIL Open Font Licence est une licence conçue par SIL International pour distribuer ses typographies, qui peuvent donc être utilisées, modifiées et distribuées librement, à la seule condition qu’elles restent sous la même licence.
-
-La licence Creative Commons BY-SA ou Attribution-ShareAlike reprend les principes de la licence Creative Commons BY en ajoutant que les oeuvres dérivées doivent être proposées au public avec les mêmes libertés que l’oeuvre originale.
-
-A côtés des licences permissives et réciproque, il y a une dernière sous-catégorie de licences libres qui sont appelées asymétriques, qui regroupent notamment la licence Creative Commons BY-NC et Creative Commons BY-ND. Ce sont des licences libre diffusion mais avec chacune des restrictions particulière
-
-La licence Creative Commons BY-NC pour Non Commercial reprend les caractéristiques de la licence Creative Commons BY mais n’autorisent qu’une utilisation non commerciale du produit. Une autorisation commerciale du produit est interdite sauf si une demande d’autorisation est acceptée.
-
-La licence Creative Commons BY-ND pour No Derivative Works n’autorise à copier, distribuer et utiliser que des versions non- modifiées de l’oeuvre. Il est possible de cumuler ces deux licences, ce qui donne la licence CC BY-NC-ND, qui autorisent l’utilisation et la redistribution de l’oeuvre mais pas de manière commerciale ni les oeuvres dérivées.
-
-On peut aussi renoncer à la quasi totalité de ses droits. Dans ce cas on peut mettre son oeuvre dans le domaine public en optant pour une licence Creative Commons 0 ou CC0 ou une licence Do What The Fuck you want to Public License ou WTFPL.
-Multi-licenciement dans le cadre d'un mémoire ou du thèse ?
-
--> besoin de licencié les différents médias sous des licenses appropriées.
-
--> possibilité de moduler en fonction de tes besoins/envies le licensiement des différents éléments de ton mémoire.
-
-Les travaux publié avec une multi-license plusieurs licenses, souvent pour permettre une utilisation commerciales ou propriétaire en même temps qu'une license open-source. Cela permet d'utiliser une création dans un projet propriétaire, ou au contraire utiliser un version copyleft et faire hérité son travail qui incorpore cette création de la license copyleft.
-Free différent de gratuit
-
-Éléments économiques autour de la licence :
-
-- changement dans la manière de consommer l’information, tout est devenu plus accessible
-
-- bien rivaux/non-rivaux
-
-- capitalisme cognitif
-
-- externalités positives qui profitent aux marchands et non-marchand
-
-- externalités négatives : environnement + questions des droits sociaux // ex Wikipédia, communautés produisent des biens communs non-rémunérées, « intelligence collective »
-Le Libre et l'Open Source ne sont pas des termes qui sous-entendent gratuit :
-
-Le terme « Free » dans l’expression « free software » signifie « libre » et non « gratuit ». Il est clairement stipulé dans la GPL, par exemple, que le distributeur peut se faire rémunérer pour l’ « acte physique de transférer une copie » (GPL art. 1). Ainsi l’on peut vendre des copies de logiciels libres. Stallman lui-même, se faisait rémunérer près de 150 $ par bande distribuée contenant les premiers « packages GNU». Cependant, une fois en possession d’une copie, l’acheteur peut utiliser, reproduire et redistribuer le programme autant de fois qu’il le désire. La vente de copies de programmes n’est certes pas la principale source de revenus des adeptes du libre.
-
-Cependant, la question de la rémunération restent un problème récurrents dans le mondes des projets open-sources. La situation est aggravé par l'utilisation des SaaS (Software As A Service) où une compagnie utilise un logiciels libres sans redistribuer et ouvrire le code du logiciels. Ils utilise une faille dans certaines licenses Copyleft, en ne redistribuant pas le code source. À la place, l'accès au logiciel se fait à travers une interface à distance, et le code source, bien qu'utilisé, n'est jamais distribué.
-
-C'est pour cela que la licenses Affrero GPL à vus le jours. Cette licenses à une clause stipulant spécifiquement que la distribution à travers un réseaux compte comme de la distribution et donc active la licenses Copyleft.
-
-Il existe à jours plusieurs méthodes de rémunération adopté par des developpeurs de logiciels open-sources: le mécénat, ou "patreon" en anglais, ou des utilisateurs généreux verse régulièrements de l'argent pour financer le développement continue du programmes, les donations, souvent à des fondations, qui sont des dons spontanée souvent ponctuels, et pour finir, l'achat de "licenses" premiums qui activent des fonctionnalités payantes, encourage //parler du mécénat et des demandes de donations, ainsi que les fondations qui se developpe pour s'assurrer qu'un ou des projets open-sources libres sous leurs tutelles ne deviennent propriétaire ou payant. L’idée sous-jacente du mouvement libre n’est pas de s’approprier les programmes informatiques afin d’en faire payer l’usage mais plutôt de se faire rémunérer sur base de services ayant trait à ces programmes (installation, customisation,...).
-
-En effet, le monde du logiciel libre est un monde d’informaticiens. Lorsque l’on parle de « libre copie » et d’accès aux sources de logiciels, il s’agit souvent de « parties de programmes » disséminées à travers l’Internet et inutilisables par le commun des mortels. Développer un « environnement » à partir de ces différentes bases requiert une personne qualifiée. De plus, une fois l’environnement créé sur un ordinateur, la maintenance ainsi que les mises à jour de cet environnement devront également être effectuées par des professionnels. Qui serait plus qualifié pour ce genre de travail que les experts en logiciels libres ?
-
-En outre, les informaticiens se servent de leur travail sur des projets libres pour se faire une réputation, qui les aidera dans leur carrière de fournisseur de service. On ne monnaiera que les améliorations apportées à l’œuvre d’origine -> Ainsi se crée un cercle vertueux incitant à la multiplication d’apports de qualité.
-
-Une des bases des logiciels libres et open-source est la contributions venant d’autres utilisateurs. Grâce à la force de travail venant des contributeurs, les logiciels libres restent sécurisé et performant.
-
-Cependant, la question de la rémunération restent un problème récurrents dans le mondes des projets open-sources. La situation est aggravé par l’utilisation des SaaS (Software As A Service) où une compagnie utilise un logiciels libres sans redistribuer et ouvrire le code du logiciels. Ils utilise une faille dans certaines licenses Copyleft, en ne redistribuant pas le code source. À la place, l’accès au logiciel se fait à travers une interface à distance, et le code source, bien qu’utilisé, n’est jamais distribué.
-
-C’est pour cela que la licenses Affrero GPL à vus le jours. Cette licenses à une clause stipulant spécifiquement que la distribution à travers un réseaux compte comme de la distribution et donc active la licenses Copyleft.
-
-Il existe à jours plusieurs méthodes de rémunération adopté par des developpeurs de logiciels open-sources: le mécénat, ou «patreon» en anglais, ou des utilisateurs généreux verse régulièrements de l’argent pour financer le développement continue du programmes, les donations, souvent à des fondations, qui sont des dons spontanée souvent ponctuels, et pour finir, l’achat de «licenses» premiums qui activent des fonctionnalités payantes, encouragents le payement du développeur.
-
-Il est important de noter que la formation des fondations se développe pour s’assurer qu’un ou des projets open-sources libres sous leurs tutelles ne deviennent propriétaire ou payant. C’est le cas de la fondation Linux, la fondation Gnome ou la Document Fundation pour en citer quelques uns.
-Propriété intellectuelle ?
-
-Les licences libres sont nées en réaction au droit de propriété intellectuelle jugé trop restrictif, et aux licences dîtes propriétaires. En effet, les licences libres permettent, au travers d’un texte, de céder une partie des droits ‘naturels’ accordés à l’auteur.e à la création d’une œuvre de l’esprit (à savoir qu’il.elle a seul.e le droit de diffuser et/ou de distribuer son œuvre).
-
-Au-delà de leur valeur juridique, elles ont également pour but de remettre en question nos relations à l’information. En effet depuis la démocratisation d’internet, une œuvre de l’esprit, peut être copiée, modifiée et diffusée pour un coût négligeable.
-
-Les licences libres s’ancrent dans le mouvement de la culture libre. Celui-ci promeut la liberté de distribuer et de modifier des œuvres de l’esprit. Le but recherché est d’encourager de manière simple et licite la circulation des œuvres, l’échange et la créativité.
-
-Cependant, aujourd’hui, la revente d’œuvres originales ou de copies constitue l’une des principales manières pour certains créateurs de se rémunérer. C’est un argument souvent invoqué par les personnes réticentes voire contre une distribution libre de l’information. Cela met en lumière que le système de propriété actuel encourage les créateurs à utiliser leurs droits pour se rémunérer. Par exemple, en France, les personnes exerçant une activité d’artiste/auteur.e doivent nécessairement générer leurs revenus par la vente de ces droits, que cela concerne la vente d’original de copie ou la cession de ces droits pour la diffusion. Sous ce régime, il n’est pas possible de se rémunérer par un contrat à taux horaire ou par des prestations de services (des ateliers par exemple, de la manintenance, tout ce qui est de l'ordre de l'execution simple et non de la création)
-Droit d’auteur
-
-La notion de droit d'auteur est profondément ancrée dans la culture occidentale, on la considère souvent comme une extension du droit naturel (ce qui peut relever d'une idéologie philosophique).
-
-L'open-source est peut-être une manière de s'en éloigner --> monde post-droits d'auteur
-
-Un dispositif de rapport de pouvoir même dans le libre...
-
-Les licences choisies par l'auteur/l'artiste, ont un pouvoir sur l'utilisateur et sur les œuvres puisqu'elles définissent la manière dont ces œuvres pourront ou non être modifiées, diffusées, appropriées, exploitées etc. Les licences ont le pouvoir d'influencer le contexte dans lequel une œuvre comme : un programme, un logiciel, une typo, une musique, ... sera " manié ".
-
-"Une licence de libre diffusion (parfois abrégé LLD) ou licence ouverte est une licence s'appliquant à une œuvre de l'esprit par laquelle l'auteur concède certains des droits que lui offre le droit d'auteur quant à l'utilisation, à la modification, à la rediffusion et à la réutilisation de l'œuvre dans des œuvres dérivées. Tout comme les licences libres dont elles dérivent et qu'elles englobent, elles facilitent la prolifération d'une œuvre en autorisant la copie et l'usage sous certaines conditions. Cependant le courant de pensée qui sous-tend les licences libres est animé par une volonté éthique d'égalité.
-
-Les licences de libre diffusion ont pour seul fondement de faciliter la diffusion, que ce soit dans une démarche d'équité ou simplement pour populariser une œuvre en limitant les frais publicitaires.
-
-On peut compter parmi les licences de libre diffusion les licences Creative Commons."
-
-Les licences libres respectent la liberté des utilisateurs, c'est une dimension éthique et sociale qui défend la liberté, l'égalité et la collaboration. Cependant, quel est le rapport de pouvoir entre une licence libre et le système économique lui-même ? Les licences libres ont le plus souvent des clauses qui permettent de définir le système de diffusion d'une œuvre et de contourner les lois en vigueur liées à la propriété intellectuelle, et par extension propriété privée.
-
-Il est favorable d'utiliser une license plutôt que pas de license : Par exemple, un code sans license est un code fermé ; on part souvent du principe que ce qui est partagé en ligne est rendu disponible. "Contre-instinct" dans un monde régi par le droit d'auteur.
-
-_______________________________________________________________________
-
-Interview avec Laurent Leprince, directeur de la BAIU (espace de consultation de documents en arts et en architecture commun aux Instituts Saint-Luc et à la faculté d’architecture LOCI de l’UCL).
-Résumé : Interview BAIU
-
-La BAIU fonctionne, depuis 2005, comme une sorte de dépôt des mémoires des institution de Saint Luc (UCLouvain, l’ERG et certaines sections de l’ESA). Les mémoires sont consultables sur place, ils ne sortent pas de la bibliothèque. Seul les mémoires ayant obtenu 70% des points sont en accès libre dans les rayons, le reste des mémoires est rangé dans les archives, où il faut remplir un document spécial afin de les consulter. Pour l’UCLouvain il existe aussi le logiciel Dial où l’on peut consulter numériquement les mémoires. Malheureusement certains étudiants restreignent l’accès à leurs mémoires, par peur du plagiat. Un des travail de Laurent est donc de réussir à convaincre les étudiants de l’intérêt d’avoir son mémoire bien indexé, disponible, et sur le fait que limiter l’accès n’est pas nécessairement une meilleure protection. Une des difficultés pour l’ERG de numériser certains projets se comprend aussi par le format non-académiques de certains mémoires.
-
-À la BAIU, les mémoires ne sont pas consultables numériquement mais grâce à un catalogue on peut avoir accès aux informations principales, savoir qu’ils existent, et quels thèmes ont été travaillés. On peut aussi, si c’est un mémoire numérique, avoir accès au site web du projet. La BAIU fait un peu au cas par cas.
-
-Cela permet aux étudiants de consulter les travaux déjà fait sur une certaine thématique afin d’aborder un angle plus original pour leur propre travail ou aux professeurs encadrant de guider les élèves en leur montrant les bons et moins bon exemples de travaux. À l’ERG, c’est Xavier Gorgol qui les amène, car l’école n’a pas la possibilité de les stocker.
-*Lancement de l’interview*
-
-Aurélie : On travaille sur les licences libres, ce que ça veut dire… et la question qu’on s’est posée, et c’est pour ça qu’on a voulu vous rencontrer, c’est, si par exemple à l’erg ou dans une autre école on cherche à licencier son mémoire, de manière à le diffuser plus largement, est-ce que c’est possible ? Au niveau de la bibliothèque et des mémoires comment est-ce que ça se passe ? Je ne sais pas de quelles écoles vous avez les mémoires ici, est-ce qu’il y a des contrats entre les écoles et vous ?
-
-Laurent Leprince : Alors ici c’est un peu compliqué parce qu’on est à cheval sur tous les instituts Saint-Luc et l’UCLouvain, et c’est vrai que les approches sont un peu différentes, donc ça peut être intéressant pour le travail. Alors au niveau des mémoires on a les mémoires d’architecture de l’UCLouvain, et puis les mémoires de l’erg et de l’esa, et l’esa c’est uniquement certaines sections. Il y a aussi d’autres instituts qui sont liés à la bibliothèque, donc Saint-Luc secondaire, où il n’y a pas de mémoire, et les cours du soir, les ateliers Saint-Luc, où il n’y en a pas non plus, sauf une section qui est l’ISRE, la formation en urbanisme mais là leurs mémoires sont conservés chez eux, donc ils ne sont pas ici. Au niveau de l’université, pour commencer, donc la formation en architecture de l’UCLouvain, jusqu’en 2017-18 c’était tous les mémoires au format papier, et après ils ont fait un dépôt institutionnel sur Dial, qui est un outil numérique de l’université. Ce qu’on a fait c’est qu’on a descendu en archives tous les mémoires papier, qui sont encore consultables, et Dial est accessible en ligne. À l’UCL, quand l’étudiant fait son dépôt dans Dial, il a la possibilité entre différents types de statut pour son mémoire, donc le mémoire peut être entièrement accessible, il peut déterminer un embargo, il peut le bloquer complètement, etc. En sachant qu’en architecture c’est parfois un peu spécifique. Par exemple on a eu des étudiants dont le TFE, chez eux ils appellent ça le Travail de Fin d’Études, consistait en la création d’une brique en papier, en matériaux recyclés et ils ont vraiment envisagé de breveter, et donc là ils ont fermé les accès. Alors qu’en art, je pense que la réflexion est peut-être différente. Là le processus est très clair, l’étudiant fait son dépôt électronique lui-même, il reçoit une formation pour ça, les professeurs les informent sur les différentes possibilités. Alors nous, on a constaté au tout début, que les étudiants fermaient les accès. J’en ai discuté avec des jobistes : « Pourquoi ? Est-ce que c’est vraiment dans ton intérêt ? « et il y en a qui ont dit « Je sais comment ça marche, je n’ai pas envie qu’on récupère des informations et donc je préfère fermer ». Alors Dial est accessible, vous pouvez aller voir et vous verrez les statistiques vous pouvez même aller année par année. Nous, on a essayé de faire passer le message d’ouvrir les accès, alors certes le travail n’est pas disponible, mais on voit où il a été déposé. Il y a aussi des logiciels comme Compilatio, qui est un logiciel de plagiat. C’est un logiciel qui moissonne toute sorte de ressources, les professeurs encodent des paragraphes et voient si ça se retrouve ailleurs. Et par exemple, à l’ULB ils utilisent ce type d’outils, et si par exemple l’étudiant bloque l’accès de son mémoire, ou donne un accès uniquement sur place, l’ULB n’a pas accès et ne peut pas inclure ce type de travail dans ses bases de données, et donc le travail est moins protégé. Donc nous on essaye d’avoir une discussion avec ces étudiants, sur le fait que ça peut être intéressant que le travail soit bien indexé, disponible, et sur le fait que limiter l’accès n’est pas nécessairement une meilleure protection. Alors l’erg, l’esa, etc, ce ne sont que des documents papiers, c’est plus un dépôt, on a pas de contrat avec l’école, je pense que le contrat est signé entre l’étudiant et l’école au moment du dépôt du mémoire.
-
-Olivia : Je pense que c’est plus au début, le papier qu’on doit signer à la rentrée.
-
-LL : Après le fait qu’un mémoire soit consultable ici ne veut pas nécessairement dire que l’étudiant autorise tout. Ici on fonctionne plus comme dépôt, c’est à dire que c’est plus un service, ce sont des mémoires papier qui sont consultables uniquement sur place, les mémoires ne sortent pas. Et alors qu’est-ce qu’il se passe ? On reçoit chaque année un certain nombre de mémoires de l’esa et de l’erg et puis nous on les encode dans le catalogue de la bibliothèque, qui est celui de l’UCLouvain, et ça par contre ça a été décidé dans le cadre d’une commission qui est la commission Art, qui est une commission qui lie la bibliothèque et les différents instituts, et c’est une commission qui vise surtout à tout ce qui est acquisition, promotion de la bibliothèque, formation... Et là on a décidé de mettre en rayon les mémoires qui ont eux 70% des points et de mettre en archives les autres, alors en archives ça ne veut pas dire qu’ils ne peuvent pas être consultés, si quelqu’un veut le consulter il y a un document à compléter et on le monte, mais dans tous les cas les mémoires ne sortiront pas . C’est parce qu’ici l’idée c’est plutôt de faire une sorte de dépôt, d’abord parce qu’à l’erg par exemple il n’y a pas la place pour, ça permet que les travaux soient disponibles pour l’ensemble des instituts Saint-Luc. En art l’approche est différente qu’en architecture, le mémoire est un objet, un livre d’artiste, au niveau de la mise en page, du type de reliure, etc., il y a tout un travail qui est fait qu’il n’y a pas toujours dans les mémoires d’architecture. Alors ça permet de vous inspirer, de connaitre les thématiques déjà traitées, si un étudiant veut être plus original par exemple ou aborder la thématique avec un angle différent, donc ce sont aussi des outils, et ça sert aussi, par exemple quand il y a des visites de profs, par exemples des profs qui encadrent un travail de recherche documentaire, ou qui encadrent le travail de mémoire, ils peuvent passer ici et dire aux étudiants qu’ils peuvent trouver les mémoires ici pour s’en inspirer, montrer des bons ou des moins bons exemples, des choses comme ça. Et alors au niveau de l’erg, c’est Xavier Gorgol qui les amène. Alors parfois quand je vais là-bas, je vois Laurence Rassel qui me donne parfois des catalogues d’expos, des choses comme ça qu’elle a sur son bureau, et s’il y a des mémoires qui trainent elle les met. Parce que c’est plus l’idée que là-bas il n’y a pas la place pour les stocker, et que comme ça c’est accessible à tout le monde. À l’esa c’est par section, on contacte les responsables des sections et on va les chercher. Alors dans le nombre de mémoires demandés, il y en a un pour le jury, il y en a aussi un pour la bibliothèque.
-
-A : Est-ce que c’est déjà arrivé qu’un étudiant refuse de donner son mémoire ? Est-ce que vous êtes au courant de ça ?
-
-LL : Ça je ne sais pas, en fait je reçois les mémoires et je demande une feuille de côte, la côte n’est pas affichée, elle est en message privé, elle est visible par les bibliothécaires mais elle n’est pas disponible en consultation dans le catalogue. Mais donc ça nous permet de voir que tel mémoire n’a pas eu les 70%, et donc il est bien en bas. Mais je n’ai pas eu de cas où quelqu’un est venu en demandant de retirer son mémoire.
-
-A : À l’esa vous disiez que c’est seulement certaines sections, ce sont lesquelles ?
-
-LL : Alors il y a Bande dessinée, Création d’intérieur, Scénographie, en fait c’est les masters, ce sont les sections qui sont passées au niveau master.
-
-Élodie : Est-ce qu’il y a des licences qui sont associées au dépôt des mémoires ou est-ce qu’il s’agit plutôt d’un contrat officieux ?
-
-LL : Je ne sais pas du tout, parce qu’on est plus un lieu de stockage. Par exemple j’avais travaillé au secrétariat à l’ISRE, où il y a des mémoires, et là c’est un contrat entre l’institut et l’étudiant au moment du dépôt.
-
-O : Avec Théophile, on avait un peu feuilleté ceux qui sont sur les étagères et dans certains il y a indiqué une licence et dans d’autres pas, donc ça dépend de l’étudiant, de s’il a pris le temps. Théophile : Et il n’y a pas cette discussion avec la bibliothèque ?
-
-LL : Dans le sens de limiter l’accès ? Non dans le sens d’ouvrir ?
-
-T : Oui, dans le sens d’ouvrir.
-
-LL : Dans le but de citer ou vraiment de récupérer ?
-
-E : Oui ça peut être copier... T : Les licences libres permettent à la fois d’utiliser, d’étudier, de copier, de modifier et de distribuer.
-
-LL : Nous on travaille plutôt dans l’optique d’un travail académique. On peut citer, mais on mentionne ses sources, et donc après ça peut être dans l’idée de « je vais distribuer mais dans le cadre de mon propre travail », et là c’est repris dans la bibliographie. Tandis que quand c’est penser à peut-être récupérer un chapitre ou des illustrations et les diffuser ou les intégrer dans un autre travail, c’est autre chose.
-
-T : Après les licences peuvent demander qu’il y ait attribution, donc qu’il y ait quand même une citation de l’auteur. Ça marche peut-être plus pour des travaux de type artistique, comme vous disiez c’est un objet, c’est un tout, et il y a peut-être moyen de s’amuser avec ça. O : Selon vous, c’est mieux que ce soit libre et qu’il y ait pas trop d’encadrement comme à l’erg, plutôt qu’on leur laisse le choix et qu’au final les accès soient limités ?
-
-LL : Je ne sais pas, après je ne sais pas comment ça se passe à l’erg, il y a peut-être un choix fait au moment du dépôt.
-
-O : Mais j’ai l’impression que même nous, étudiants, on est pas vraiment au courant, même qu’il y a des mémoires ici à la bibliothèque, je pense que beaucoup l’apprennent par après.
-
-LL : Ils s’en réjouissent ou pas ?
-
-T : On ne sait pas, on devrait essayer de voir ça. O : En tout cas, on dirait qu’ils ne sont pas tant au courant de ça qu’il y a des mémoires ici.
-
-LL : Par exemple je sais qu’il y a des profs qui ont fait un travail, je ne sais plus si c’était en graphisme, qui ont fait une réédition de certains mémoires de qualité, ça vous dit quelque chose ?
-
-A : Ah oui j’ai vu ça.
-
-LL : Ils ont demandé de pouvoir consulter tous les mémoires, et là on a remonté même ceux qui n’avaient pas obtenus les 70%, et il y a eu une présélection par les étudiants, c’était avec Renaud Huberlant.
-
-Justine : Et ceux dont les mémoires ont été sélectionnés ont été contactés ?
-
-LL : Ça je ne sais pas.
-
-T : Et comment ils sont listés, il y a un index de ceux qui sont en-dessous de 70% ?
-
-LL : Il y a un index, il y a moyen dans le catalogue de les retrouver. Ils sont tous dans le catalogue.
-
-A : Et la limite des 70%, elle a été définie comment ?
-
-LL : C’est par la commission Art, ça a du être dans des PV, mais c’est plus pour des questions pédagogiques, c’est parce que le but ici c’est plus de mettre à disposition des exemples, et c’est un signal pour dire que c’est un travail de qualité.
-
-A : J’ai encore une question, ici, il y a les mémoires d’architecture, de l’erg et de Saint-Luc, est-ce qu’il y a d’autres endroits où se trouvent ces mémoires ou c’est exclusif à la bibliothèque ?
-
-LL : C’est exclusif à la bibliothèque mais le catalogue est commun avec l’UCLouvain. Mais comme les mémoires ne bougent pas, ils ne peuvent être consultés qu’ici. Sauf sur Dial, la base de données en ligne, et là effectivement ils sont consultables partout, ou limités au réseau UCLouvain, et là c’est consultable seulement sur place. Après ça c’est une question d’infrastructures aussi, c’est des serveurs, c’est assez lourds, parce que ce sont des serveurs qui servent aussi pour les publications scientifiques, et puis c’est aussi des différences d’objets, il y a pas mal de mémoires artistiques, ça serait plus difficile de les mettre sur ce genre de plateforme, parce que c’est quand même assez formaté, c’est du pdf. En architecture, il y a parfois aussi plus de créativité, parce qu’en architecture c’est aussi différent, c’est un TFE en et sur l’architecture, et chez eux le projet prime, donc en fait, ils ont un TFE à faire, mais ça s’articule avec leur travail d’atelier et le TFE approfondit souvent un aspect, et la thématique ou le site ou le bâtiment sont liés, et dans une partie plus théorique ils vont traiter d’une thématique liée. Il y a aussi des évolutions par exemple à l’esa. Au début les mémoires de l’erg étaient beaucoup plus créatifs, à l’esa ils étaient très scolaires, moins objets, et maintenant il y a plus de recherche, par exemple avec des formats différents, etc. Mais à l’esa ça reste plus une réflexion sur, alors qu’à l’erg le mémoire est parfois un objet artistique aussi, même s’il est pensé, indexé, réfléchi, c’est assez différent parfois, et ça varie aussi avec les sections je pense. Je vais vous montrer Dial. Vous pouvez choisir par année, par promoteur, par faculté, par type de diplôme, et ici vous avez les informations sur les accès : restreint, libre, interdit, mixte ou embargo. Embargo, c’est à dire que ça sera accessible après un certain nombre d’années, par exemple en médecine, en pharmacie, chez les ingénieurs ça peut se justifier, par exemple s’il y a des brevets ou des choses comme ça. Ou alors parfois même en sciences économiques, quand il y a des gens qui travaillent avec des sociétés, l’entreprise peut dire : « Vous pouvez faire le travail avec nous mais il ne doit être disponible que dans 5 ans pour des raisons de concurrence », ou il y a des données confidentielles... Libre c’est qu’il n’y a pas de restrictions, interdit c’est quand rien du tout n’est accessible, restreint c’est restreint au réseau UCL, et mixte ça veut dire qu’il y a plusieurs documents et que tous les documents n’ont pas la même protection. Par exemple, mon travail théorique je le rends public mais les annexes, dans le cadre d’un travail avec une entreprise ou autre, je mets un embargo ou j’interdis l’accès. Par contre le titre du mémoire, le résumé, sont publics, et on retrouve les promoteurs... Libellule c’est le catalogue de la bibliothèque, il dessert l’UCLouvain, L’Unamur et L’Université Saint-Louis. Les mémoires sont répertoriés dedans. Ça vaut peut-être le coup d’aller voir comment ça se passe pour les mémoires au niveau des écoles d’art en France, ou du côté néerlandophone aussi. Après je sais qu’il y a aussi du coté des universités, l’ULiège par exemple, ont beaucoup développé tout ce qui est l’open-source etc.
-
-A : J’ai encore une question, est-ce que c’est déjà arrivé, qu’une fois qu’un étudiant sorte de master, il finisse par publier son mémoire, avec un éditeur par exemple ?
-
-LL : Je n’en ai pas connaissance, je sais qu’à l’esa, j’ai entendu parler d’étudiantes qui publiaient des articles, je sais qu’il y a un étudiant qui a fait un très bon travail sur les chalets norvégiens à l’esa, et lui a peut-être envie de faire une publication. Je sais qu’il a eu un prix, mais pour le moment le mémoire est consultable ici.
-
-T : Faut se dépêcher.
-
-LL : (rires) Après je pense que ça va être retravaillé. On a quelques ouvrages en architecture qui sont devenus des références aussi mais ce sont plus des ouvrages qui recensent par exemple tous les bâtiments construits par un architecte, des gens qui font une sorte d’inventaire qui n’existe nulle part ailleurs, et donc ça devient une référence que les gens consultent régulièrement.
-
- Visite des archives*
-
-A : Au niveau des mémoires, est-ce que vous avez une obligation de conservation, une responsabilité, par exemple si les mémoires qui sont en haut...
-
-LL : ... disparaissent ?
-
-A : Oui ou si avec le temps ils s’abîment, parce que ce sont des choses qui sont relativement uniques, ce sont des choses qui sont édités à 3 ou 4 exemplaires.
-
-LL : Je ne sais pas, j’ai un collègue qui fait une formation en archivistique, qui a eu pas mal de cours sur les aspects juridiques.
-
-O : Et ça fait combien de temps que les mémoires sont ici, qu’ils sont archivés ? Et la bibliothèques existe depuis combien de temps ?
-
-LL : Alors ici c’est depuis 2011, et avant c’était un centre de documentation à Saint-Luc, rue d’Irlande, depuis plus longtemps encore. Alors là ce sont les mémoires, ici ce sont d’autres institutions, on conserve des mémoires ou des thèses de doctorat parce que ce sont des thématiques intéressantes, il y a aussi un centre d’archives d’architectes, ce sont des architectes dont les familles ont fait don des archives, ça peut être des plans... Et c’est disponible ici pour les consulter. Par exemple Bastin, c’est un architecte qui a réalisé une aile du musée d’art moderne, un jour il y a eu des fuites et le bâtiment était menacé, des gens chargés de la restauration sont venus ici consulter les archives pour savoir comment ça avait été fait, les matériaux, etc.
-
-T : La limite des 70%, c’est pour toutes les écoles ?
-
-LL : Oui c’est pour tout le monde. Et il y a autre chose que je n’ai pas dit. C’est vrai que la limite des 70% continue à s’appliquer à l’université. Si l’étudiant décide que l’accès est libre, mais que le travail n’a pas atteint les 70%, l’université peut bloquer l’accès, peut décider que l’ouvrage n’est pas consultable. Par contre si l’étudiant interdit l’accès, l’université ne peut pas l’y obliger. Et ça c’est surtout pour qu’il n’y ait pas des travaux qui circulent, qui ne soient pas assez bons.
-
-O : Est-ce que pour l’erg, qui fonctionne plus comme un dépôt, par exemple l’année passée avec le COVID, il y a des mémoires qui manquent, par qu’ils n’ont pas été imprimés ou autre ?
-
-LL : Alors effectivement il y a des trous.
-
-T : Vous savez ça comment ?
-
-LL : En comparant les mémoires qu’on reçoit et les PV de délibérations. Alors parfois, par exemple j’ai dit à un jobiste dont le mémoire n’était pas arrivé qu’il pouvait le ramener, il ne l’a pas fait, mais par contre si un étudiant vient en disant qu’on a pas reçu son mémoire et qu’il voudrait qu’il figure à la bibliothèque, on n’a aucun soucis.
-
-T : Vous ne stockez que les versions papiers, c’est ce qui est requis par l’école si je comprends bien ?
-
-LL : Oui.
-
-T : Mais du coup si quelqu’un rendait un travail numérique ?
-
-LL : Ça c’est un peu un problème, on a eu quelques fois le cas avec des travaux de l’erg, où le truc, c’est parfois juste une sorte de petite étiquette avec un code barre ou des choses comme ça, alors ça c’est un peu délicat.
-
-T : Vous n’avez pas d’espace numérique ?
-
-LL : Non, et en fait Dial est vraiment limité à l’UCLouvain. Donc souvent dans ce cas-là, ce que les étudiants font, c’est qu’ils ont une sorte de domaine internet et ils publient leur mémoire là- dessus, et puis 3/4 ans après ils se disent : « Ça ne m’intéresse plus, je ne paye plus » et le travail disparaît. Des étudiants de l’UCLouvain avaient proposé une solution, je crois qu’il y a moyen d’archiver en ligne. On l’avait fait, parce qu’on pouvait se le permettre, ça concernait un cas ou deux. Mais si ça devient de plus en plus régulier, alors ça pose la question d’un serveur ou d’autres choses.
-
-T : Est-ce qu’on peut voir dans le catalogue le nombre de mémoires qui ont été faits au format numérique ?
-
-LL : Je ne pense pas, parfois c’est sous forme de podcast, c’est de l’audio, alors parfois on garde ça sur un CD-Rom, mais bon les CDs ont une durée de vie limitée, mais bon commencer à archiver ça sur un disque dur c’est complexe. Parce que c’est vrai que tout a des fins pédagogiques, la base c’est que c’est à des fins pédagogiques. Donc tu parlais d’obligation tout à l’heure, on est plus dans l’idée d’archivage, parce qu’il n’y a pas la place à l’erg, et donc plutôt que de laisser ça dans un placard, ça vient ici, parce que c’est une manière de rendre les choses accessibles et consultables par les profs et les étudiants. C’est une autre finalité.
-
-O : Et donc pour l’erg ça commence en 2005 ?
-
-LL : Oui c’est ça. Et je pense qu’au tout début, il y avait énormément de mémoires ici, parce que la qualité ne suivait pas, mais petit à petit ça s’est relevé. Quand les étudiants de Renaud sont venus, ils ont récupérés une partie de ceux-là, parce qu’ils regardaient surtout l’objet. C’est compliqué d’avoir quelqu’un qui a une démarche scientifique et aussi artistique. Alors il y en a certains que l’on conserve un double, c’est un peu ce que tu disais, s’il y en a qui disparaissent. Et on ne les numérise pas nous.
-
-T : J’ai vu qu’il y avait écrit « numériser » sur des cartons juste derrière, qu’est-ce que vous numérisez du coup ?
-
-LL : Ça ce sont des VHS, et Aurélien les numérise.
-
-A : J’ai encore des questions. Quand c’est un mémoire numérique, sous forme de site web par exemple, est-ce qu’ils sont répertoriés quelque part ?
-
-LL : Ils sont d’office répertoriés dans le catalogue, et donc dans le type, il y aura « papier, autant de page », ou alors ça sera écrit « site web ». Alors nous on essayait, quand c’était rare, de conserver un back-up si l’étudiant nous en fournissaient un, ou si ce n’est qu’un site on fournissait le lien, mais si un jour l’étudiant arrête de payer son nom de domaine, il n’y a plus rien. Après, je sais qu’on l’avais fait une fois, on avait cherché des solutions intermédiaires, on avait archivé en ligne. Mais c’est vraiment au cas par cas, il n’y a rien de prévu de manière automatique.
-
-T : Oui, il faudrait voir alors.
-
-LL : Oui, prévoir un serveur à l’erg.
-
-O : Ou que la bibliothèque soit aussi un appui numérique. T : Je suis pas sûr qu’il faille un serveur, juste un disque dur ça doit suffire, il faut juste un espace de stockage numérique. O : Depuis combien de temps la bibliothèque existe ?
-
-LL : Le centre de documentation à StLuc date de 1968.
-
-________________________________________________________
-CONCLUSION du travail sur les licences
-
-Au premier quadrimestre, nous avons abordé les thémes du libre et de l'open source (licences et logiciels), et les rapports de pouvoir qui s'y jouent, à un niveau théorique. Au second quadrimestre, nous avons voulu voir les implications du libre d'un point de vue plus pratique, et plus spécifiquement, en rapport avec les mémoires, travail qui nous concerne toustes. Existe-t-il une licence qui s'applique automatiquement aux mémoires de l'ERG ? Si oui, comment faisons-nous pour l'appliquer à nos projets ? Avons-nous la possibilité d'utiliser différentes licences et comment ? Comment les adapter en fonction des spécificités de certains types de mémoires (numériques, artistiques) ? Où sont stockés nos travaux ? Son-ils accessibles ?
-
-Dans nos recherches, nous avons interrogé des acteurs de l'administration qui encadre le suivi et l'archivage des travaux (Laurent Leprince de la BAIU et Xavier Gorgol de l'ERG). Nous avons pu discuter des raisons qui poussaient certains étudiants à fermer l'accès à leurs mémoires, en pensant, à tort, mieux les protéger.
-
-On a également commencé une base de données pour comparer les différentes caractéristiques des licences libres. À partir de cette base de données, nous avons mis en forme un flyers contenant les licences libres les plus réccurentes dans le cadre des projets artistiques, afin de clarifier et d'aider les étudiant à licencier leurs mémoires. Pas seulement un outil de diffusion, les licences peuvent aussi être support d'une vision ; exemple avec la collective Bye bye Binary qui a travers ses recherches typographiques et sa licence cherche à diffuser l'écriture inclusive. Leur licence libre OIFL (OpenInclusif..veFonteLicense) ,es tune adaptation en français et en écriture inclusive de l'OFL. Autre exemple, la revue trimestrielle Médor qui adopte le parti de ne fonctionner qu'avec des outils libres et dont le code du site internet est émis en licence libre (licence BSD). Le livret est un compte-rendu de tout le travail effectué durant ce quadrimestre et des recherches engagées. Il permet de mieux s’informer sur le libre et sert également de guide aux étudiants qui souhaiteraient trouver des alternatives libre de création dans le numérique et dans la rédaction/mise sous licence de leur futur mémoire.
diff --git a/docs/DATABASE_CONFIG.md b/docs/DATABASE_CONFIG.md
deleted file mode 100644
index b1b7fca..0000000
--- a/docs/DATABASE_CONFIG.md
+++ /dev/null
@@ -1,181 +0,0 @@
-# Database Configuration
-
-This document explains the centralized database configuration for the Post-ERG thesis management system.
-
-## Overview
-
-Database paths are centralized in `shared/config.php` to provide a single source of truth for:
-- Test database location (development)
-- Production database location (deployment)
-- Environment detection logic
-
-## Database Locations
-
-```
-database/
-├── test.db # Development/testing database
-└── posterg.db # Production database
-```
-
-## Configuration File
-
-The `shared/config.php` file defines:
-
-```php
-// Test database (development)
-DB_TEST_PATH = '/path/to/storage/test.db'
-
-// Production database (server)
-DB_PROD_PATH = '/path/to/storage/posterg.db'
-```
-
-## How It Works
-
-### Automatic Detection
-
-By default, the system automatically determines which database to use:
-
-1. **If `storage/test.db` exists** → Use test database (development mode)
-2. **Otherwise** → Use production database (production mode)
-
-This means:
-- Developers get test database automatically when it exists
-- Production server uses production database (no test.db present)
-
-### Manual Override
-
-You can force a specific database using the `DB_ENV` environment variable:
-
-```bash
-# Force test database
-export DB_ENV=test
-php apps/public/index.php
-
-# Force production database
-export DB_ENV=prod
-php apps/public/index.php
-```
-
-### Custom Path Override
-
-You can also pass a custom database path directly:
-
-```php
-// Use specific database file
-$db = new Database('/custom/path/to/database.db');
-
-// Or with singleton
-$db = Database::getInstance('/custom/path/to/database.db');
-```
-
-## Deployment Workflow
-
-### Development
-
-When working locally:
-```bash
-# Create test database with fixtures
-just create-fixtures
-
-# Start development server (uses test.db automatically)
-just serve-public
-just serve-admin
-```
-
-### Production
-
-When deploying to server:
-```bash
-# Deploy applications and shared code (excludes test.db automatically)
-just deploy
-
-# The deploy command explicitly excludes:
-# - test.db (test database)
-# - *.db (all database files)
-# - tests/ (test suites)
-# - cache/ (temporary files)
-# - *.md (documentation)
-
-# Result: Only posterg.db exists on server
-# Application automatically uses production database
-```
-
-### Deploying Test Database (Explicitly)
-
-If you need to deploy the test database to the server (for testing):
-```bash
-# This is a separate, explicit command
-just test-deploy
-
-# ⚠️ Warning: This will overwrite the remote test.db file
-```
-
-### Deploying Database Structure Only
-
-To deploy schema and fixtures without databases:
-```bash
-# Deploy schema.sql and fixtures/ only (excludes all .db files)
-just deploy-database
-```
-
-### Testing on Production
-
-To test with production data locally:
-```bash
-# Download production database (optional)
-scp posterg:/var/www/html/storage/posterg.db database/
-
-# Remove test database to force production mode
-rm database/test.db
-
-# Or set environment variable
-export DB_ENV=prod
-php apps/public/index.php
-```
-
-## Benefits of Centralized Configuration
-
-1. **Single source of truth** - All database paths defined in one place
-2. **Environment-aware** - Automatically detects development vs production
-3. **Override capability** - Can force specific database when needed
-4. **Maintainable** - Easy to update paths or add new environments
-5. **Safe deployment** - Test database never deployed to production
-
-## Integration with Database Class
-
-The `Database` class automatically uses this configuration:
-
-```php
-require_once 'shared/Database.php';
-
-// Automatically uses correct database based on environment
-$db = new Database();
-```
-
-The path resolution order is:
-1. Custom path (if provided)
-2. `DB_ENV` environment variable
-3. Auto-detection (test.db exists → test mode, otherwise → production)
-
-## Helper Functions
-
-`shared/config.php` provides helper functions:
-
-```php
-// Get current database path
-$path = getDatabasePath();
-
-// Check if running in test mode
-if (isTestMode()) {
- echo "Using test database";
-}
-```
-
-## Notes
-
-- **Deployment safety**: The `deploy`, `deploy-public`, and `deploy-admin` recipes explicitly exclude `test.db` and all `*.db` files
-- **Explicit test deploy**: Use `just test-deploy` to explicitly deploy test.db when needed
-- **Git ignored**: Test database is in `.gitignore` and never committed
-- **Backups**: Production database should be backed up regularly
-- **Schema**: Both databases use the same schema (`storage/schema.sql`)
-- **Verification**: Run `rsync --dry-run` to preview what will be deployed before deploying
diff --git a/docs/DATABASE_SPECIFICATION.md b/docs/DATABASE_SPECIFICATION.md
deleted file mode 100644
index e68ce83..0000000
--- a/docs/DATABASE_SPECIFICATION.md
+++ /dev/null
@@ -1,887 +0,0 @@
-# Post-ERG Database Specification
-
-Complete technical specification of the Post-ERG thesis database schema.
-
-**Version:** 1.0
-**Database:** SQLite
-**Last Updated:** February 5, 2026
-
----
-
-## 📋 Table of Contents
-
-1. [Overview](#overview)
-2. [Entity Relationship Diagram](#entity-relationship-diagram)
-3. [Core Tables](#core-tables)
-4. [Lookup Tables](#lookup-tables)
-5. [Junction Tables](#junction-tables)
-6. [Support Tables](#support-tables)
-7. [Views](#views)
-8. [Indexes](#indexes)
-9. [Triggers](#triggers)
-10. [Data Types Reference](#data-types-reference)
-11. [Business Rules](#business-rules)
-12. [Sample Queries](#sample-queries)
-
----
-
-## Overview
-
-### Purpose
-Database for managing and publishing ERG final thesis projects (TFE - Travaux de Fin d'Études) and doctoral theses.
-
-### Key Features
-- Multi-author thesis support
-- Multiple supervisors per thesis
-- Flexible format types (web, audio, video, print, etc.)
-- Access control (public, internal, restricted)
-- File attachment management
-- Keyword tagging system
-- Full-text search capability
-- Academic metadata tracking
-
-### Database Size Estimates
-- **Expected records**: 100-500 theses/year
-- **Growth rate**: ~10-15% annually
-- **Average record size**: ~5KB (metadata only)
-- **File storage**: External (linked via file paths)
-
----
-
-## Entity Relationship Diagram
-
-```
-┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
-│ authors │◄──────│ thesis_authors │──────►│ theses │
-└─────────────┘ 1:N └──────────────────┘ N:1 └─────────────┘
- │
-┌─────────────┐ ┌──────────────────┐ │
-│supervisors │◄──────│thesis_supervisors│──────────────┘
-└─────────────┘ 1:N └──────────────────┘ N:1
-
-┌─────────────┐ ┌──────────────────┐
-│ keywords │◄──────│ thesis_keywords │──────────────┐
-└─────────────┘ 1:N └──────────────────┘ N:1 │
- │
-┌─────────────┐ ┌──────────────────┐ │
-│ languages │◄──────│ thesis_languages │──────────────┤
-└─────────────┘ 1:N └──────────────────┘ N:1 │
- │
-┌─────────────┐ ┌──────────────────┐ │
-│format_types │◄──────│ thesis_formats │──────────────┤
-└─────────────┘ 1:N └──────────────────┘ N:1 │
- │
-┌─────────────┐ │
-│orientations │──────────────────────────────────────────┤
-└─────────────┘ 1:N N:1 │
- │
-┌─────────────┐ │
-│ ap_programs │──────────────────────────────────────────┤
-└─────────────┘ 1:N N:1 │
- │
-┌─────────────┐ │
-│finality_types│─────────────────────────────────────────┤
-└─────────────┘ 1:N N:1 │
- │
-┌─────────────┐ │
-│access_types │──────────────────────────────────────────┤
-└─────────────┘ 1:N N:1 │
- │
-┌─────────────┐ │
-│license_types│──────────────────────────────────────────┤
-└─────────────┘ 1:N N:1 │
- │
-┌─────────────┐ │
-│thesis_files │──────────────────────────────────────────┘
-└─────────────┘ N:1
-```
-
----
-
-## Core Tables
-
-### `theses`
-**Purpose:** Main table storing thesis/dissertation information.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `identifier` | TEXT | YES | NULL | Unique identifier (e.g., "2025-002") |
-| `title` | TEXT | NO | - | Thesis title |
-| `subtitle` | TEXT | YES | NULL | Optional subtitle |
-| `year` | INTEGER | NO | - | Academic year of submission |
-| `is_doctoral` | BOOLEAN | NO | 0 | 0 = TFE (Master), 1 = Doctoral thesis |
-| `orientation_id` | INTEGER | YES | NULL | FK to `orientations` |
-| `ap_program_id` | INTEGER | YES | NULL | FK to `ap_programs` (Ateliers Pratiques) |
-| `finality_id` | INTEGER | YES | NULL | FK to `finality_types` |
-| `synopsis` | TEXT | YES | NULL | ~200 word summary |
-| `context_note` | TEXT | YES | NULL | Note by jury president (max 150 words) |
-| `remarks` | TEXT | YES | NULL | Internal administrative remarks |
-| `duration_minutes` | INTEGER | YES | NULL | For audio/video works |
-| `duration_pages` | INTEGER | YES | NULL | For written works |
-| `file_size_info` | TEXT | YES | NULL | Human-readable size (e.g., "128 pages + 45 minutes") |
-| `access_type_id` | INTEGER | YES | NULL | FK to `access_types` |
-| `license_id` | INTEGER | YES | NULL | FK to `license_types` |
-| `jury_points` | DECIMAL(4,2) | YES | NULL | Grade out of 20 |
-| `jury_note_added` | BOOLEAN | NO | 0 | Whether jury added a context note |
-| `submitted_at` | DATETIME | YES | NULL | Student submission timestamp |
-| `defense_date` | DATETIME | YES | NULL | Date of thesis defense |
-| `published_at` | DATETIME | YES | NULL | Public publication timestamp |
-| `is_published` | BOOLEAN | NO | 0 | Publication status |
-| `baiu_link` | TEXT | YES | NULL | Link to institutional repository (BAIU) |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-| `updated_at` | DATETIME | NO | CURRENT_TIMESTAMP | Last update time |
-
-**Indexes:**
-- `idx_theses_year` ON `year`
-- `idx_theses_published` ON `is_published`
-- `idx_theses_identifier` ON `identifier`
-- `idx_theses_orientation` ON `orientation_id`
-- `idx_theses_ap_program` ON `ap_program_id`
-- `idx_theses_access_type` ON `access_type_id`
-
-**Constraints:**
-- `identifier` must be UNIQUE
-- `year` must be > 1950 (implicit validation)
-- `jury_points` must be between 0 and 20 (implicit validation)
-
----
-
-### `authors`
-**Purpose:** Store student/author information.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Author full name |
-| `email` | TEXT | YES | NULL | Contact email |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-| `updated_at` | DATETIME | NO | CURRENT_TIMESTAMP | Last update time |
-
-**Indexes:**
-- `idx_authors_email` ON `email`
-
-**Notes:**
-- Same author can have multiple theses
-- Email is optional (privacy)
-- No uniqueness constraint on name (same names possible)
-
----
-
-### `supervisors`
-**Purpose:** Store thesis supervisor/promoter information.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Supervisor full name |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-| `updated_at` | DATETIME | NO | CURRENT_TIMESTAMP | Last update time |
-
-**Notes:**
-- Reusable across multiple theses
-- No email/contact info stored (administrative data)
-
----
-
-## Lookup Tables
-
-### `orientations`
-**Purpose:** Predefined list of artistic orientations.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Orientation name |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Predefined Values:**
-1. Arts Numériques
-2. Dessin
-3. Cinéma d'animation
-4. Installation-Performance
-5. Peinture
-6. Photographie
-7. Sculpture
-8. Vidéographie
-9. Graphisme
-10. Typographie
-11. Design Numérique
-12. Illustration
-13. Bande-Dessinée
-14. Sérigraphie
-15. Gravure
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `ap_programs`
-**Purpose:** Practical workshops programs (Ateliers Pratiques).
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Program full name |
-| `code` | TEXT | YES | NULL | Short code/acronym |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Predefined Values:**
-1. Narration Spéculative (no code)
-2. Design et Politique du Multiple (DPM)
-3. Atelier Pratiques Situées (APS)
-4. Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes (LIENS)
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `finality_types`
-**Purpose:** Master degree finality types.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Finality type name |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Predefined Values:**
-1. Approfondi (Research-focused)
-2. Enseignement (Teaching)
-3. Spécialisé (Specialized)
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `languages`
-**Purpose:** Languages used in thesis.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Language name |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Predefined Values:**
-1. Français
-2. Anglais
-
-**Notes:**
-- Expandable if needed (Dutch, etc.)
-- Thesis can be multilingual (junction table)
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `format_types`
-**Purpose:** Physical/digital format types.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Format type name |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Predefined Values:**
-1. Site web
-2. Audio
-3. Vidéo
-4. Performance
-5. Objet éditorial (printed matter)
-6. Installation
-7. Autre (other)
-
-**Notes:**
-- Multiple formats per thesis allowed
-- "Autre" for edge cases
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `access_types`
-**Purpose:** Define thesis accessibility levels.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | Access type name |
-| `description` | TEXT | YES | NULL | Detailed description |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Predefined Values:**
-
-| ID | Name | Description |
-|----|------|-------------|
-| 1 | Libre | Full access online and in library |
-| 2 | Interne | Physical access only; descriptive note online |
-| 3 | Interdit | No access; descriptive note online only |
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `license_types`
-**Purpose:** Creative Commons and other license types.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `name` | TEXT | NO | - | License name (e.g., "CC BY-SA 4.0") |
-| `description` | TEXT | YES | NULL | License description |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Expected Values:**
-- CC BY 4.0
-- CC BY-SA 4.0
-- CC BY-NC 4.0
-- CC BY-NC-SA 4.0
-- CC0 1.0
-- All Rights Reserved
-- Custom (text description)
-
-**Constraints:**
-- `name` must be UNIQUE
-
----
-
-### `keywords`
-**Purpose:** Expandable keyword/tag list.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `keyword` | TEXT | NO | - | Keyword/tag text |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-
-**Notes:**
-- Keywords are case-insensitive (normalized to lowercase)
-- Maximum 10 keywords per thesis (enforced in application)
-- Auto-created when first used
-- Can be reused across theses
-
-**Constraints:**
-- `keyword` must be UNIQUE
-
----
-
-## Junction Tables
-
-### `thesis_authors`
-**Purpose:** Many-to-many relationship between theses and authors.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `thesis_id` | INTEGER | NO | - | FK to `theses.id` |
-| `author_id` | INTEGER | NO | - | FK to `authors.id` |
-| `author_order` | INTEGER | NO | 1 | Display order (1, 2, 3...) |
-
-**Primary Key:** (`thesis_id`, `author_id`)
-
-**Cascade Rules:**
-- ON DELETE CASCADE (both FKs)
-
-**Notes:**
-- Single author: `author_order = 1`
-- Multiple authors: ordered by `author_order`
-
----
-
-### `thesis_supervisors`
-**Purpose:** Many-to-many relationship between theses and supervisors.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `thesis_id` | INTEGER | NO | - | FK to `theses.id` |
-| `supervisor_id` | INTEGER | NO | - | FK to `supervisors.id` |
-| `supervisor_order` | INTEGER | NO | 1 | Display order |
-
-**Primary Key:** (`thesis_id`, `supervisor_id`)
-
-**Cascade Rules:**
-- ON DELETE CASCADE (both FKs)
-
----
-
-### `thesis_languages`
-**Purpose:** Many-to-many relationship between theses and languages.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `thesis_id` | INTEGER | NO | - | FK to `theses.id` |
-| `language_id` | INTEGER | NO | - | FK to `languages.id` |
-
-**Primary Key:** (`thesis_id`, `language_id`)
-
-**Cascade Rules:**
-- ON DELETE CASCADE (both FKs)
-
----
-
-### `thesis_formats`
-**Purpose:** Many-to-many relationship between theses and format types.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `thesis_id` | INTEGER | NO | - | FK to `theses.id` |
-| `format_id` | INTEGER | NO | - | FK to `format_types.id` |
-
-**Primary Key:** (`thesis_id`, `format_id`)
-
-**Cascade Rules:**
-- ON DELETE CASCADE (both FKs)
-
----
-
-### `thesis_keywords`
-**Purpose:** Many-to-many relationship between theses and keywords.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `thesis_id` | INTEGER | NO | - | FK to `theses.id` |
-| `keyword_id` | INTEGER | NO | - | FK to `keywords.id` |
-
-**Primary Key:** (`thesis_id`, `keyword_id`)
-
-**Indexes:**
-- `idx_thesis_keywords_thesis` ON `thesis_id`
-- `idx_thesis_keywords_keyword` ON `keyword_id`
-
-**Cascade Rules:**
-- ON DELETE CASCADE (both FKs)
-
-**Business Rules:**
-- Maximum 10 keywords per thesis (enforced in application layer)
-
----
-
-## Support Tables
-
-### `thesis_files`
-**Purpose:** Store file attachments for theses.
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `thesis_id` | INTEGER | NO | - | FK to `theses.id` |
-| `file_type` | TEXT | NO | - | Type: 'main', 'annex', 'written_part', 'other' |
-| `file_path` | TEXT | NO | - | Relative path to file |
-| `file_name` | TEXT | NO | - | Original filename |
-| `file_size` | INTEGER | YES | NULL | Size in bytes |
-| `mime_type` | TEXT | YES | NULL | MIME type (e.g., 'application/pdf') |
-| `description` | TEXT | YES | NULL | File description |
-| `uploaded_at` | DATETIME | NO | CURRENT_TIMESTAMP | Upload timestamp |
-
-**Cascade Rules:**
-- ON DELETE CASCADE on `thesis_id`
-
-**File Types:**
-- **main**: Primary thesis document (PDF, HTML, etc.)
-- **annex**: Supplementary materials
-- **written_part**: Written component of practice-based thesis
-- **other**: Additional files
-
-**Notes:**
-- Files stored in `/var/www/html/formulaire/data/theses/`
-- Cover images stored in `/var/www/html/formulaire/data/covers/`
-
----
-
-### `pages`
-**Purpose:** Static content management (About, Licenses, Contact, etc.).
-
-| Column | Type | Null | Default | Description |
-|--------|------|------|---------|-------------|
-| `id` | INTEGER | NO | AUTOINCREMENT | Primary key |
-| `slug` | TEXT | NO | - | URL-friendly identifier |
-| `title` | TEXT | NO | - | Page title |
-| `content` | TEXT | YES | NULL | Page content (Markdown/HTML) |
-| `is_published` | BOOLEAN | NO | 1 | Publish status |
-| `created_at` | DATETIME | NO | CURRENT_TIMESTAMP | Record creation time |
-| `updated_at` | DATETIME | NO | CURRENT_TIMESTAMP | Last update time |
-
-**Predefined Pages:**
-- `charte` - Site charter/policy
-- `about` - About page
-- `licenses` - License information
-- `contact` - Contact page
-
-**Constraints:**
-- `slug` must be UNIQUE
-
----
-
-## Views
-
-### `v_theses_full`
-**Purpose:** Complete thesis information with all relationships joined.
-
-**Columns:**
-- All columns from `theses`
-- `orientation` (TEXT) - Orientation name
-- `ap_program` (TEXT) - AP program name
-- `finality_type` (TEXT) - Finality type name
-- `access_type` (TEXT) - Access type name
-- `license_type` (TEXT) - License name
-- `authors` (TEXT) - Comma-separated author names
-- `supervisors` (TEXT) - Comma-separated supervisor names
-- `languages` (TEXT) - Comma-separated language names
-- `formats` (TEXT) - Comma-separated format names
-- `keywords` (TEXT) - Comma-separated keywords
-
-**Usage:**
-```sql
-SELECT * FROM v_theses_full WHERE id = 123;
-```
-
-**Notes:**
-- Uses `GROUP_CONCAT` for many-to-many relationships
-- Results are comma-delimited strings
-- May need post-processing for proper arrays
-
----
-
-### `v_theses_public`
-**Purpose:** Published theses only (for public website).
-
-**Definition:**
-```sql
-SELECT * FROM v_theses_full WHERE is_published = 1;
-```
-
-**Usage:**
-```sql
-SELECT * FROM v_theses_public ORDER BY year DESC, title;
-```
-
----
-
-## Indexes
-
-### Performance Indexes
-
-| Index Name | Table | Columns | Purpose |
-|------------|-------|---------|---------|
-| `idx_theses_year` | `theses` | `year` | Filter by year |
-| `idx_theses_published` | `theses` | `is_published` | Public/private filtering |
-| `idx_theses_identifier` | `theses` | `identifier` | Unique lookup |
-| `idx_theses_orientation` | `theses` | `orientation_id` | Filter by orientation |
-| `idx_theses_ap_program` | `theses` | `ap_program_id` | Filter by AP program |
-| `idx_theses_access_type` | `theses` | `access_type_id` | Access control |
-| `idx_authors_email` | `authors` | `email` | Author lookup |
-| `idx_thesis_authors_thesis` | `thesis_authors` | `thesis_id` | Join optimization |
-| `idx_thesis_authors_author` | `thesis_authors` | `author_id` | Join optimization |
-| `idx_thesis_keywords_thesis` | `thesis_keywords` | `thesis_id` | Join optimization |
-| `idx_thesis_keywords_keyword` | `thesis_keywords` | `keyword_id` | Keyword search |
-
----
-
-## Triggers
-
-### Timestamp Update Triggers
-
-**`update_theses_timestamp`**
-```sql
-AFTER UPDATE ON theses
-UPDATE theses SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
-```
-
-**`update_authors_timestamp`**
-```sql
-AFTER UPDATE ON authors
-UPDATE authors SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
-```
-
-**`update_supervisors_timestamp`**
-```sql
-AFTER UPDATE ON supervisors
-UPDATE supervisors SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
-```
-
-**`update_pages_timestamp`**
-```sql
-AFTER UPDATE ON pages
-UPDATE pages SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
-```
-
----
-
-## Data Types Reference
-
-### SQLite Data Types Used
-
-| Type | SQLite Affinity | Description | Example Values |
-|------|----------------|-------------|----------------|
-| `INTEGER` | INTEGER | Signed integer | 1, 42, 2025 |
-| `TEXT` | TEXT | Variable-length text | "Title", "Name" |
-| `BOOLEAN` | INTEGER | 0 or 1 | 0 (false), 1 (true) |
-| `DATETIME` | TEXT | ISO8601 timestamp | "2025-02-05 12:00:00" |
-| `DECIMAL(4,2)` | REAL | Decimal number | 15.50, 18.75 |
-
-### Boolean Convention
-- `FALSE` = 0
-- `TRUE` = 1
-- NULL = undefined/not set
-
----
-
-## Business Rules
-
-### Thesis Submission Workflow
-
-1. **Draft Creation** (`is_published = 0`)
- - Student creates initial entry
- - Required fields: title, year, at least one author
-
-2. **Complete Metadata**
- - Add orientation, AP program, finality
- - Upload files
- - Add keywords (max 10)
- - Set languages, formats
-
-3. **Submission** (`submitted_at` set)
- - Student marks as ready for review
- - Email notification to administrators
-
-4. **Defense** (`defense_date` set)
- - After thesis defense
- - Jury adds grade (`jury_points`)
- - Optional context note by jury president
-
-5. **Publication** (`is_published = 1`, `published_at` set)
- - Administrator approves
- - Appears on public website
- - Respects `access_type` rules
-
-### Data Validation Rules
-
-**Required Fields (for publication):**
-- `title`
-- `year`
-- At least one author (via `thesis_authors`)
-- `orientation_id`
-- `access_type_id`
-
-**Optional but Recommended:**
-- `synopsis` (~200 words)
-- `keywords` (3-10 recommended)
-- At least one file attachment
-- `license_id`
-
-**Constraints:**
-- `year`: Must be ≥ 1950
-- `jury_points`: 0.00 to 20.00
-- `keywords`: Maximum 10 per thesis
-- `author_order`: Must be sequential (1, 2, 3...)
-- `identifier`: Unique across all theses
-
-### Access Control Rules
-
-| Access Type | Public View | Library Access | File Download |
-|-------------|-------------|----------------|---------------|
-| **Libre** | Full metadata + abstract | Yes | Yes |
-| **Interne** | Metadata + descriptive note | Physical only | No |
-| **Interdit** | Metadata + descriptive note | No | No |
-
----
-
-## Sample Queries
-
-### Common Queries
-
-**Get all published theses from 2025:**
-```sql
-SELECT * FROM v_theses_public
-WHERE year = 2025
-ORDER BY title;
-```
-
-**Find theses by author name:**
-```sql
-SELECT t.* FROM theses t
-JOIN thesis_authors ta ON t.id = ta.thesis_id
-JOIN authors a ON ta.author_id = a.id
-WHERE a.name LIKE '%Dupont%'
-AND t.is_published = 1;
-```
-
-**Get thesis with all relationships:**
-```sql
-SELECT * FROM v_theses_full WHERE id = 42;
-```
-
-**List theses by orientation:**
-```sql
-SELECT t.title, t.year, o.name as orientation
-FROM theses t
-JOIN orientations o ON t.orientation_id = o.id
-WHERE o.name = 'Arts Numériques'
-AND t.is_published = 1
-ORDER BY t.year DESC;
-```
-
-**Full-text search in titles and synopses:**
-```sql
-SELECT * FROM v_theses_public
-WHERE title LIKE '%design%'
- OR synopsis LIKE '%design%'
-ORDER BY year DESC;
-```
-
-**Get theses by keyword:**
-```sql
-SELECT DISTINCT t.* FROM theses t
-JOIN thesis_keywords tk ON t.id = tk.thesis_id
-JOIN keywords k ON tk.keyword_id = k.id
-WHERE k.keyword = 'écologie'
-AND t.is_published = 1;
-```
-
-**Count theses per year:**
-```sql
-SELECT year, COUNT(*) as count
-FROM theses
-WHERE is_published = 1
-GROUP BY year
-ORDER BY year DESC;
-```
-
-**Get theses with files:**
-```sql
-SELECT t.title, tf.file_name, tf.file_type
-FROM theses t
-JOIN thesis_files tf ON t.id = tf.thesis_id
-WHERE t.is_published = 1
-ORDER BY t.title;
-```
-
-**Find theses without keywords:**
-```sql
-SELECT t.* FROM theses t
-LEFT JOIN thesis_keywords tk ON t.id = tk.thesis_id
-WHERE tk.thesis_id IS NULL
-AND t.is_published = 1;
-```
-
-### Administrative Queries
-
-**Recently submitted theses (pending review):**
-```sql
-SELECT title, submitted_at
-FROM theses
-WHERE submitted_at IS NOT NULL
-AND is_published = 0
-ORDER BY submitted_at DESC;
-```
-
-**Theses missing required metadata:**
-```sql
-SELECT id, title, year
-FROM theses
-WHERE (orientation_id IS NULL
- OR access_type_id IS NULL
- OR id NOT IN (SELECT thesis_id FROM thesis_authors))
-AND is_published = 0;
-```
-
-**Most used keywords:**
-```sql
-SELECT k.keyword, COUNT(*) as usage_count
-FROM keywords k
-JOIN thesis_keywords tk ON k.id = tk.keyword_id
-GROUP BY k.keyword
-ORDER BY usage_count DESC
-LIMIT 20;
-```
-
-**Theses by supervisor:**
-```sql
-SELECT s.name as supervisor, COUNT(*) as thesis_count
-FROM supervisors s
-JOIN thesis_supervisors ts ON s.id = ts.supervisor_id
-JOIN theses t ON ts.thesis_id = t.id
-WHERE t.is_published = 1
-GROUP BY s.name
-ORDER BY thesis_count DESC;
-```
-
----
-
-## Making Schema Changes
-
-### How to Request Changes
-
-When requesting schema changes, please specify:
-
-1. **What needs to change**
- - Table name
- - Column name(s)
- - Relationship
-
-2. **Type of change**
- - Add new table
- - Add new column
- - Modify existing column
- - Remove column/table
- - Change relationship
-
-3. **Why it's needed**
- - Use case
- - Business requirement
- - Performance issue
-
-4. **Example data**
- - Sample values
- - Expected format
-
-### Example Change Request
-
-```
-**Change Request:** Add support for thesis awards/distinctions
-
-**Type:** Add new table + relationship
-
-**Reason:** Need to track prizes and awards given to theses
-(e.g., "Best TFE 2025", "Jury Prize")
-
-**Proposed Structure:**
-- Table: `awards`
- - id (INT, PK)
- - name (TEXT) - Award name
- - description (TEXT) - Award description
- - year (INT) - Year established
-
-- Table: `thesis_awards`
- - thesis_id (INT, FK)
- - award_id (INT, FK)
- - awarded_date (DATETIME)
-
-**Example Data:**
-- "Prix du Jury 2025"
-- "Meilleur TFE Arts Numériques"
-- "Prix de l'Innovation"
-```
-
----
-
-## Version History
-
-| Version | Date | Changes |
-|---------|------|---------|
-| 1.0 | 2026-02-05 | Initial specification document |
-
----
-
-**For questions or change requests, reference this document and provide:**
-- Section name
-- Table/column affected
-- Desired outcome
-- Example use case
diff --git a/docs/DEPLOYMENT_MIGRATION.md b/docs/DEPLOYMENT_MIGRATION.md
deleted file mode 100644
index 65a6e34..0000000
--- a/docs/DEPLOYMENT_MIGRATION.md
+++ /dev/null
@@ -1,571 +0,0 @@
-# Deployment & Dev Server Migration Guide
-
-Analysis of current `justfile` and required changes for the new directory structure.
-
----
-
-## 🔍 Current Setup Analysis
-
-### Current Dev Server (❌ INCORRECT)
-```bash
-# From justfile line 33
-php -S 127.0.0.1:8000
-```
-
-**Problems:**
-- Serves from project root (all files accessible via web)
-- Exposes sensitive files: `storage/`, `tests/`, `vendor/`, config files
-- Doesn't match production DocumentRoot configuration
-- Security risk: `.env`, database files, source code all accessible
-
-### Current Deployment (❌ INCORRECT)
-```bash
-# From justfile lines 56-75
-rsync -vur --progress \
- --exclude 'vendor' --exclude 'tests' --exclude '*.db' ... \
- ./ posterg:/var/www/html/
-```
-
-**Problems:**
-- Deploys entire project to DocumentRoot
-- Relies on exclusions to hide sensitive files (error-prone)
-- Wrong structure: `/var/www/html/` should only contain public files
-- Private files (`src/`, `config/`) are still in DocumentRoot
-- Nginx serves from `/var/www/html/` exposing everything not excluded
-
----
-
-## ✅ Required Changes
-
-### 1. New Directory Structure on Server
-
-**Before (current):**
-```
-/var/www/html/ # DocumentRoot ❌
-├── index.php # Public
-├── search.php # Public
-├── admin/ # Public (protected by nginx)
-├── assets/ # Public
-├── inc/ # ❌ EXPOSED (config files!)
-├── lib/ # ❌ EXPOSED (source code!)
-├── database/ # ❌ EXPOSED (database files!)
-└── vendor/ # ❌ (excluded but in wrong place)
-```
-
-**After (recommended):**
-```
-/var/www/posterg/ # Application root (private)
-├── public/ # DocumentRoot ✅ (only this exposed)
-│ ├── index.php
-│ ├── search.php
-│ ├── memoire.php
-│ ├── admin/
-│ └── assets/
-├── src/ # ✅ PRIVATE
-├── config/ # ✅ PRIVATE
-├── database/ # ✅ PRIVATE
-├── vendor/ # ✅ PRIVATE
-├── var/ # ✅ PRIVATE (cache, logs)
-└── lib/ # ✅ PRIVATE
-```
-
----
-
-## 📝 Updated Justfile
-
-### Change 1: Dev Server
-
-**Current:**
-```just
-[group('dev')]
-serve:
- @echo "🚀 Starting Post-ERG development server"
- @echo "📍 Public site: http://localhost:8000"
- @echo "📍 Admin panel: http://localhost:8000/admin/"
- @php -S 127.0.0.1:8000
-```
-
-**New:**
-```just
-[group('dev')]
-serve:
- @echo "🚀 Starting Post-ERG development server"
- @echo "========================================"
- @echo ""
- @echo "📍 Public site: http://localhost:8000"
- @echo "📍 Admin panel: http://localhost:8000/admin/"
- @echo ""
- @echo "🔒 Serving from public/ directory (matches production)"
- @echo ""
- @if [ -d "vendor/php-live-reload" ]; then \
- echo "✨ Live reload enabled - browser auto-refreshes on file save!"; \
- else \
- echo "💡 Tip: Run 'just setup' to enable live reload"; \
- fi
- @echo ""
- @echo "Press Ctrl+C to stop"
- @echo ""
- @php -S 127.0.0.1:8000 -t public/
-
-# Alternative: If you need router script for URL rewriting
-[group('dev')]
-serve-router:
- @echo "🚀 Starting with router script (for clean URLs)"
- @php -S 127.0.0.1:8000 -t public/ public/router.php
-```
-
-**Key change:** `-t public/` flag tells PHP server to use `public/` as DocumentRoot
-
----
-
-### Change 2: Deployment Strategy
-
-**Current (❌):**
-```just
-deploy:
- rsync -vur --progress \
- --exclude 'vendor' --exclude 'tests' ... \
- ./ posterg:/var/www/html/
-```
-
-**New (✅) - Two-Step Deployment:**
-
-```just
-[group('deploy')]
-deploy:
- @echo "📤 Deploying Post-ERG site"
- @echo "=========================="
- @echo ""
- @echo "Step 1: Deploying application files..."
-
- # Deploy entire application to private directory
- rsync -vur --progress \
- --exclude '.git*' \
- --exclude '.jj' \
- --exclude 'tests/' \
- --exclude 'docs/' \
- --exclude '*.md' \
- --exclude 'justfile*' \
- --exclude 'setup-dev.sh' \
- --exclude 'migrate-structure.sh' \
- --exclude 'database/test.db' \
- --exclude 'database/backup_*' \
- --exclude 'database/fixtures/' \
- --exclude 'var/cache/*' \
- --exclude 'var/logs/*' \
- --exclude '.DS_Store' \
- ./ posterg:/var/www/posterg/
-
- @echo ""
- @echo "Step 2: Setting up directory structure..."
-
- # Create necessary directories on server
- ssh posterg "mkdir -p /var/www/posterg/var/{cache,logs,tmp} && \
- chown -R www-data:posterg /var/www/posterg/var && \
- chmod -R 775 /var/www/posterg/var"
-
- @echo ""
- @echo "Step 3: Setting permissions..."
-
- # Set correct ownership and permissions
- ssh posterg "cd /var/www/posterg && \
- chown -R www-data:posterg . && \
- find . -type d -exec chmod 755 {} \; && \
- find . -type f -exec chmod 644 {} \; && \
- chmod -R 775 var/ && \
- chmod -R 775 database/ && \
- chmod 660 database/*.db"
-
- @echo ""
- @echo "✅ Deployment complete!"
- @echo ""
- @echo "🔍 Verify deployment:"
- @echo " • Public: https://posterg.erg.be/"
- @echo " • Admin: https://posterg.erg.be/admin/"
- @echo ""
- @echo "📁 Server structure:"
- @echo " • App root: /var/www/posterg/"
- @echo " • DocumentRoot: /var/www/posterg/public/"
-
-# Quick deploy - only public files (faster for frontend changes)
-[group('deploy')]
-deploy-public:
- @echo "⚡ Quick deploy: public files only"
- rsync -vur --progress \
- --delete \
- ./public/ posterg:/var/www/posterg/public/
- @echo "✅ Public files updated"
-
-# Deploy only code (no assets)
-[group('deploy')]
-deploy-code:
- @echo "⚡ Deploying PHP code only"
- rsync -vur --progress \
- --include='**.php' \
- --include='**/' \
- --exclude='*' \
- ./ posterg:/var/www/posterg/
- @echo "✅ Code updated"
-```
-
----
-
-### Change 3: Database Deployment
-
-**Current:**
-```just
-test-deploy:
- ssh posterg "mkdir -p /var/www/html/database"
- rsync -vur --progress ./storage/test.db posterg:/var/www/html/storage/test.db
-```
-
-**New:**
-```just
-[group('deploy')]
-deploy-database:
- @echo "📊 Deploying database..."
- @echo "⚠️ This will overwrite the remote database!"
- @read -p "Continue? [y/N] " -n 1 -r; \
- echo; \
- if [[ $$REPLY =~ ^[Yy]$$ ]]; then \
- ssh posterg "mkdir -p /var/www/posterg/database" && \
- rsync -vur --progress ./storage/test.db posterg:/var/www/posterg/storage/ && \
- ssh posterg "chown www-data:posterg /var/www/posterg/storage/test.db && \
- chmod 660 /var/www/posterg/storage/test.db" && \
- echo "✅ Database deployed"; \
- else \
- echo "❌ Cancelled"; \
- fi
-
-# Backup remote database before deploying
-[group('deploy')]
-backup-remote-db:
- @echo "💾 Backing up remote database..."
- @ssh posterg "sqlite3 /var/www/posterg/storage/test.db .dump" > database/remote_backup_$(date +%Y%m%d_%H%M%S).sql
- @echo "✅ Remote database backed up locally"
-```
-
----
-
-### Change 4: Updated Nginx Deployment
-
-**Current nginx configuration probably points to:**
-```nginx
-root /var/www/html;
-```
-
-**Should change to:**
-```nginx
-root /var/www/posterg/public;
-```
-
-**Updated recipe:**
-```just
-[group('server')]
-deploy-nginx:
- @echo "🔧 Deploying nginx configuration..."
- @echo ""
- @echo "⚠️ IMPORTANT: Nginx config must point to /var/www/posterg/public"
- @echo ""
-
- # Check if nginx config has correct DocumentRoot
- @if ! grep -q "/var/www/posterg/public" nginx/posterg.conf 2>/dev/null; then \
- echo "❌ ERROR: nginx/posterg.conf doesn't contain '/var/www/posterg/public'"; \
- echo " Update DocumentRoot before deploying!"; \
- exit 1; \
- fi
-
- rsync -vur --progress ./nginx/posterg.conf posterg:/tmp/posterg.conf
- rsync -vur --progress ./nginx/deploy-production.sh posterg:/tmp/deploy-production.sh
-
- @echo "✅ Files uploaded to /tmp/ on server"
- @echo ""
- @echo "Next steps on the server:"
- @echo " ssh posterg"
- @echo " sudo bash /tmp/deploy-production.sh"
-```
-
----
-
-## 🔧 Nginx Configuration Changes
-
-### Update `nginx/posterg.conf`
-
-**Find and replace:**
-```nginx
-# OLD
-root /var/www/html;
-
-# NEW
-root /var/www/posterg/public;
-```
-
-**Complete example:**
-```nginx
-server {
- listen 80;
- listen [::]:80;
- server_name posterg.erg.be;
-
- # Redirect to HTTPS
- return 301 https://$server_name$request_uri;
-}
-
-server {
- listen 443 ssl http2;
- listen [::]:443 ssl http2;
- server_name posterg.erg.be;
-
- # NEW DocumentRoot - only public directory
- root /var/www/posterg/public;
- index index.php index.html;
-
- # SSL configuration
- ssl_certificate /etc/letsencrypt/live/posterg.erg.be/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/posterg.erg.be/privkey.pem;
-
- # Logs
- access_log /var/log/nginx/posterg_access.log;
- error_log /var/log/nginx/posterg_error.log;
-
- # Security headers
- add_header X-Frame-Options "SAMEORIGIN" always;
- add_header X-Content-Type-Options "nosniff" always;
- add_header X-XSS-Protection "1; mode=block" always;
-
- # Deny access to sensitive files (should already be outside public/)
- location ~ /\. {
- deny all;
- }
-
- location ~ /storage/ {
- deny all;
- }
-
- # Admin area - basic auth
- location /admin/ {
- auth_basic "Admin Access";
- auth_basic_user_file /etc/nginx/.htpasswd;
-
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
- fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
- # IMPORTANT: Set correct SCRIPT_FILENAME
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- }
- }
-
- # PHP files
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
- fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- }
-
- # Static files
- location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
- expires 1y;
- add_header Cache-Control "public, immutable";
- }
-
- # Deny access to uploaded files execution
- location ~ ^/uploads/.*\.php$ {
- deny all;
- }
-}
-```
-
----
-
-## 🔄 Migration Steps
-
-### Step 1: Local Development
-```bash
-# 1. Create new structure
-mkdir -p public/{admin,assets}
-mkdir -p src config var/{cache,logs,tmp}
-
-# 2. Move public files
-mv index.php search.php memoire.php public/
-mv assets/* public/assets/
-mv admin/* public/admin/
-
-# 3. Move private files
-mv inc/* config/ # or src/ depending on content
-mv lib src/lib
-
-# 4. Update paths in PHP files (see PATHS_UPDATE.md below)
-
-# 5. Test local dev server
-just serve
-# Opens http://localhost:8000
-# Verify that sensitive files return 404:
-# http://localhost:8000/storage/test.db → 404
-# http://localhost:8000/config/ → 404
-# http://localhost:8000/src/ → 404
-```
-
-### Step 2: Update Nginx Config
-```bash
-# Edit nginx/posterg.conf
-# Change: root /var/www/html;
-# To: root /var/www/posterg/public;
-
-# Validate locally
-nginx -t -c nginx/posterg.conf
-```
-
-### Step 3: Deploy
-```bash
-# 1. Backup current production
-ssh posterg "tar -czf /tmp/posterg-backup-$(date +%Y%m%d).tar.gz /var/www/html"
-
-# 2. Create new directory structure
-ssh posterg "mkdir -p /var/www/posterg"
-
-# 3. Deploy application
-just deploy
-
-# 4. Deploy nginx config
-just deploy-nginx
-
-# 5. On server: activate new config
-ssh posterg
-sudo bash /tmp/deploy-production.sh
-
-# 6. Reload nginx
-sudo systemctl reload nginx
-
-# 7. Test
-just server-status
-```
-
----
-
-## 🧪 Testing Checklist
-
-### Local Testing
-- [ ] `just serve` starts on port 8000
-- [ ] Public site loads: http://localhost:8000
-- [ ] Admin loads: http://localhost:8000/admin/
-- [ ] Assets load (CSS, images, JS)
-- [ ] Database files NOT accessible via browser
-- [ ] Config files NOT accessible via browser
-- [ ] Tests still pass: `just test`
-
-### Production Testing
-- [ ] HTTPS works: https://posterg.erg.be/
-- [ ] Admin login works
-- [ ] Search functionality works
-- [ ] Database connections work
-- [ ] File uploads work (if applicable)
-- [ ] Logs written to `/var/www/posterg/var/logs/`
-- [ ] Sensitive URLs return 404:
- - https://posterg.erg.be/storage/test.db
- - https://posterg.erg.be/config/
- - https://posterg.erg.be/src/
- - https://posterg.erg.be/vendor/
-
----
-
-## 📊 Path Changes Summary
-
-| File Type | Current Path | New Path |
-|-----------|-------------|----------|
-| Public index | `/index.php` | `/public/index.php` |
-| Admin panel | `/admin/` | `/public/admin/` |
-| Assets | `/assets/` | `/public/assets/` |
-| Config | `/inc/` | `/config/` or `/src/` |
-| Libraries | `/lib/` | `/src/lib/` |
-| Database | `/storage/` | `/storage/` (stays) |
-| Vendor | `/vendor/` | `/vendor/` (stays) |
-| Tests | `/tests/` | `/tests/` (stays) |
-
----
-
-## 🔒 Security Improvements
-
-### Before
-- ❌ All files in DocumentRoot
-- ❌ Relies on nginx deny rules
-- ❌ One misconfiguration = full exposure
-- ❌ Database accessible if nginx fails
-
-### After
-- ✅ Only `public/` in DocumentRoot
-- ✅ Physical separation of public/private
-- ✅ Nginx misconfiguration = site down (not exposed)
-- ✅ Database physically unreachable via web
-
----
-
-## 💡 Tips
-
-### Router Script (for clean URLs)
-Create `public/router.php` for development:
-```php
-
-```
-
----
-
-## Migration Checklist
-
-- [ ] `just setup-server` - Create server directory
-- [ ] `just deploy` - Deploy application
-- [ ] `just deploy-nginx` - Update nginx config
-- [ ] SSH to server and apply nginx config
-- [ ] `sudo systemctl reload nginx`
-- [ ] Verify site works: https://posterg.erg.be/
-- [ ] Verify security: https://posterg.erg.be/storage/test.db → 404
-- [ ] Test admin: https://posterg.erg.be/admin/
-- [ ] Deploy database (if needed): `just deploy-database`
-
----
-
-## Commands Reference
-
-| Command | Purpose |
-|---------|---------|
-| `just setup-server` | Create `/var/www/posterg/` (first time only) |
-| `just deploy` | Deploy application files |
-| `just deploy-nginx` | Update nginx configuration |
-| `just deploy-database` | Deploy database file |
-| `just server-status` | Check server health |
-| `just server-logs` | View server logs |
-
----
-
-## Directory Structure on Server
-
-```
-/var/www/posterg/ # Application root (private)
-├── public/ # DocumentRoot (nginx points here)
-│ ├── index.php
-│ ├── search.php
-│ ├── memoire.php
-│ ├── admin/
-│ └── assets/
-├── includes/ # Templates (private)
-├── config/ # Configuration (private)
-├── database/ # Database (private)
-├── lib/ # PHP classes (private)
-└── vendor/ # Dependencies (private)
-```
-
-**Nginx DocumentRoot:** `/var/www/posterg/public/`
-
-Only the `public/` directory is accessible via web browser. Everything else is private.
diff --git a/docs/DEVELOPMENT_GUIDE.md b/docs/DEVELOPMENT_GUIDE.md
deleted file mode 100644
index 1d22d94..0000000
--- a/docs/DEVELOPMENT_GUIDE.md
+++ /dev/null
@@ -1,507 +0,0 @@
-# Post-ERG Development Guide
-
-Complete guide for developing the Post-ERG thesis management system.
-
-## 🚀 Quick Start
-
-### 1. Setup (One Time)
-
-```bash
-# Clone php-live-reload and setup directories
-just setup
-```
-
-### 2. Start Development Server
-
-```bash
-just serve
-```
-
-This starts **one unified server** at:
-- **Public site:** http://localhost:8000
-- **Admin panel:** http://localhost:8000/admin/
-
-✨ **Live reload enabled** - your browser auto-refreshes when you save files!
-
-### 3. Edit & Watch
-
-Edit any PHP file and watch your browser automatically refresh! 🎉
-
----
-
-## 📁 Project Structure
-
-```
-posterg-website/
-├── index.php # Public homepage
-├── memoire.php # Thesis detail page
-├── search.php # Search page
-├── *.php # Other public pages
-│
-├── admin/ # Admin panel
-│ ├── index.php # Admin dashboard
-│ ├── list.php # Thesis list
-│ ├── edit.php # Edit thesis
-│ └── formulaire.php # Add thesis
-│
-├── lib/ # Shared libraries
-│ ├── Database.php # Database class
-│ ├── RateLimit.php # Rate limiting
-│ └── config.php # Configuration
-│
-├── inc/ # Page templates
-│ ├── header.php # Site header
-│ └── footer.php # Site footer
-│
-├── assets/ # Static files
-│ ├── posterg.css # Main CSS
-│ └── fonts/ # Custom fonts
-│
-├── database/ # Database
-│ ├── schema.sql # Schema definition
-│ ├── test.db # Test database
-│ └── fixtures/ # Sample data
-│
-├── tests/ # Test suite
-│ ├── Unit/ # Unit tests
-│ ├── Integration/ # Integration tests
-│ └── Security/ # Security tests
-│
-└── vendor/ # Third-party (gitignored)
- └── php-live-reload/
-```
-
----
-
-## 🛠️ Development Workflow
-
-### Starting Development
-
-```bash
-# Start the development server
-just serve
-
-# In your browser:
-# - Public site: http://localhost:8000
-# - Admin panel: http://localhost:8000/admin/
-```
-
-### Making Changes
-
-1. **Edit PHP files** - Auto-refreshes browser
-2. **Edit CSS** - Auto-refreshes browser
-3. **Test changes** - See them instantly!
-
-### Running Tests
-
-```bash
-# Run all tests
-just test
-
-# Run specific test suites
-just test-unit # Unit tests
-just test-integration # Integration tests
-just test-security # Security tests
-```
-
-### Database Operations
-
-```bash
-# View database stats
-just stats
-
-# Open SQLite shell
-just query
-
-# Show specific thesis
-just show 42
-
-# Reset database
-just reset-db
-
-# Create with sample data
-just fixtures
-```
-
----
-
-## 📝 Common Tasks
-
-### Create a New Page
-
-1. Create `newpage.php` in root
-2. Add `require_once __DIR__ . '/src/Database.php';`
-3. Include header: `include 'inc/header.php';`
-4. Add your content
-5. Include footer: `include 'inc/footer.php';`
-
-Example:
-```php
-
-
-
-
-
My New Page
-
Content here...
-
-
-
-
-```
-
-### Add a Database Function
-
-1. Edit `src/Database.php`
-2. Add your method to the `Database` class
-3. Write a test in `tests/Unit/DatabaseTest.php`
-4. Run tests: `just test-unit`
-
-### Update CSS
-
-1. Edit `assets/posterg.css`
-2. Browser auto-refreshes!
-3. (Optional) Increment version in `inc/header.php`: `posterg.css?v=3`
-
-### Add a Test
-
-1. Choose location:
- - `tests/Unit/` - For testing classes/functions
- - `tests/Integration/` - For testing workflows
- - `tests/Security/` - For testing security
-
-2. Create test file (e.g., `tests/Unit/MyTest.php`)
-
-3. Follow the template in `tests/README.md`
-
-4. Add to `tests/run-tests.php`
-
-5. Run: `just test`
-
----
-
-## 🧪 Testing
-
-### Test Database
-
-Development uses `storage/test.db` (gitignored).
-
-**Create test database:**
-```bash
-just init-db
-```
-
-**Populate with sample data:**
-```bash
-just fixtures
-```
-
-**Deploy test database to server:**
-```bash
-just deploy-test-db
-```
-
-**Reset everything:**
-```bash
-just reset-db
-```
-
-### Writing Tests
-
-See `tests/README.md` for complete testing guide.
-
-**Quick example:**
-```php
-getMessage() . "\n";
- return false;
-}
-```
-
----
-
-## 🚀 Deployment
-
-### Deploy Everything
-
-```bash
-just deploy
-```
-
-This deploys:
-- Public site (root PHP files)
-- Admin panel (`admin/`)
-- Shared libraries (`src/`)
-
-**Note:** `vendor/` is automatically excluded from deployment.
-
-### Deploy Selectively
-
-```bash
-# Deploy only the code
-just deploy
-
-# Deploy test database
-just deploy-test-db
-
-# Deploy nginx config
-just deploy-nginx
-
-# Deploy admin tools
-just deploy-admin-tools
-```
-
----
-
-## 🔧 Justfile Commands
-
-### Development
-
-| Command | Description |
-|---------|-------------|
-| `just setup` | Setup development environment (one-time) |
-| `just serve` | Start development server with live reload |
-| `just stop` | Stop development server |
-| `just logs` | View development logs |
-
-### Testing
-
-| Command | Description |
-|---------|-------------|
-| `just test` | Run all tests |
-| `just test-unit` | Run unit tests |
-| `just test-integration` | Run integration tests |
-| `just test-security` | Run security tests |
-| `just syntax` | Check PHP syntax |
-
-### Database
-
-| Command | Description |
-|---------|-------------|
-| `just init-db` | Create test database |
-| `just reset-db` | Reset test database |
-| `just query` | Open SQLite shell |
-| `just show ` | Show thesis by ID |
-| `just backup` | Backup database |
-| `just fixtures` | Create sample data |
-| `just deploy-test-db` | Deploy test database to server |
-
-### Statistics
-
-| Command | Description |
-|---------|-------------|
-| `just stats` | Show database statistics |
-| `just recent` | Show recent theses |
-
-### Deployment
-
-| Command | Description |
-|---------|-------------|
-| `just deploy` | Deploy complete site |
-| `just deploy-nginx` | Deploy nginx configuration |
-| `just deploy-admin-tools` | Deploy admin user management |
-
-### Server
-
-| Command | Description |
-|---------|-------------|
-| `just server-logs` | View server logs |
-| `just server-status` | Check server status |
-
-### Utilities
-
-| Command | Description |
-|---------|-------------|
-| `just clean` | Clean up dev files |
-| `just setup-dirs` | Create data directories |
-
----
-
-## 💡 Tips & Tricks
-
-### Live Reload
-
-The `just serve` command uses php-live-reload to automatically refresh your browser when you save files.
-
-**What triggers refresh:**
-- Saving any `.php` file
-- Saving any file in the project
-
-**How it works:**
-- WebSocket connection monitors file changes
-- Browser receives reload signal
-- Page refreshes automatically
-
-**No browser extension needed!**
-
-### Multiple Browser Windows
-
-Open multiple browser windows/tabs - they all get live reload!
-
-```
-http://localhost:8000/ # Public site
-http://localhost:8000/admin/ # Admin panel
-http://localhost:8000/memoire.php?id=13 # Specific thesis
-```
-
-All will auto-refresh when you save files! ✨
-
-### Using a Real Test Database
-
-The test database (`storage/test.db`) is gitignored. To share test data:
-
-```bash
-# Create fixtures
-just fixtures
-
-# Commit the fixtures generator
-git add database/fixtures/
-git commit -m "Update test fixtures"
-```
-
-Others can recreate with: `just fixtures`
-
-### Debugging
-
-**Check error logs:**
-```bash
-just logs
-```
-
-**Or directly:**
-```bash
-tail -f error.log
-```
-
-**PHP errors in browser:**
-Edit your PHP file temporarily:
-```php
-ini_set('display_errors', 1);
-error_reporting(E_ALL);
-```
-
-**Database issues:**
-```bash
-# Check database exists
-ls -lh database/test.db
-
-# Open database shell
-just query
-
-# Check tables
-sqlite> .tables
-
-# Show schema
-sqlite> .schema theses
-```
-
----
-
-## 🔍 Troubleshooting
-
-### Server won't start
-
-**Port already in use:**
-```bash
-just stop
-# Or manually:
-pkill -f "php -S 127.0.0.1:8000"
-```
-
-**php-live-reload missing:**
-```bash
-just setup
-```
-
-### Live reload not working
-
-**Check vendor directory:**
-```bash
-ls -la vendor/php-live-reload/
-```
-
-**Reinstall:**
-```bash
-rm -rf vendor/php-live-reload
-just setup
-```
-
-### Database errors
-
-**Database not found:**
-```bash
-just init-db
-```
-
-**Permissions error:**
-```bash
-chmod 644 database/test.db
-```
-
-**Schema errors:**
-```bash
-just reset-db
-```
-
-### Tests failing
-
-**Run individual test:**
-```bash
-php tests/Unit/DatabaseTest.php
-```
-
-**Check database:**
-```bash
-just stats
-```
-
-**Reset database:**
-```bash
-just reset-db
-just fixtures
-just test
-```
-
----
-
-## 📚 Further Reading
-
-- [Test Documentation](../tests/README.md)
-- [Database Specification](../storage/DATABASE_SPECIFICATION.md)
-- [Migration Guide](../MIGRATION_GUIDE.md)
-- [Deployment Guide](../nginx/DEPLOYMENT_COMPLETE.md)
-
----
-
-## ✨ Quick Reference
-
-**Start developing:**
-```bash
-just setup # One time
-just serve # Start server
-```
-
-**Test your changes:**
-```bash
-just test # Run tests
-just stats # Check database
-```
-
-**Deploy to production:**
-```bash
-just deploy
-```
-
-That's it! Happy coding! 🚀
diff --git a/docs/DIRECTORY_STRUCTURE.md b/docs/DIRECTORY_STRUCTURE.md
deleted file mode 100644
index a67e9fe..0000000
--- a/docs/DIRECTORY_STRUCTURE.md
+++ /dev/null
@@ -1,246 +0,0 @@
-# Recommended Directory Structure
-
-Based on the **Standard PHP Package Skeleton** (researched by Paul M. Jones from thousands of GitHub projects).
-
-## Directory Layout
-
-```
-posterg-website/
-├── public/ # DocumentRoot - publicly accessible files
-│ ├── index.php # Front controller
-│ ├── assets/ # Public assets (CSS, JS, images)
-│ │ ├── css/
-│ │ ├── js/
-│ │ └── images/
-│ └── .htaccess # Apache/nginx rules
-│
-├── src/ # Application source code (private)
-│ ├── Controller/ # Controllers
-│ ├── Model/ # Models
-│ ├── View/ # Views/templates
-│ ├── Service/ # Business logic services
-│ ├── Repository/ # Data access layer
-│ └── Middleware/ # Middleware components
-│
-├── config/ # Configuration files (private)
-│ ├── app.php
-│ ├── database.php
-│ ├── routes.php
-│ └── .env.example # Environment variables template
-│
-├── database/ # Database-related files
-│ ├── migrations/ # Database migrations
-│ ├── seeds/ # Database seeders
-│ └── schema.sql # Database schema
-│
-├── tests/ # Unit and integration tests
-│ ├── Unit/
-│ ├── Integration/
-│ └── bootstrap.php
-│
-├── vendor/ # Third-party dependencies (Composer)
-│ └── autoload.php
-│
-├── bin/ # Executable scripts
-│ └── console # CLI commands
-│
-├── var/ # Variable/temporary files (private)
-│ ├── cache/ # Application cache
-│ ├── logs/ # Log files
-│ └── tmp/ # Temporary files
-│
-├── docs/ # Documentation
-│ └── *.md
-│
-├── scripts/ # Build/deployment scripts
-│ └── deploy.sh
-│
-├── resources/ # Non-PHP resources (private)
-│ ├── views/ # Template files
-│ ├── lang/ # Translations
-│ └── emails/ # Email templates
-│
-├── lib/ # Internal libraries (if not using src/)
-│
-├── .git/ # Git repository
-├── .gitignore
-├── composer.json # Composer dependencies
-├── composer.lock
-├── phpunit.xml # PHPUnit configuration
-├── README.md # Project documentation
-└── LICENSE # License file
-```
-
-## Directory Purposes
-
-### **public/** (PUBLIC - DocumentRoot points here)
-- **Only directory accessible via web browser**
-- Contains: front controller (index.php), assets (CSS/JS/images)
-- Web server DocumentRoot should point to this directory
-- Security: No sensitive files here
-
-### **src/** (PRIVATE)
-- Application source code
-- All classes following PSR-4 autoloading
-- Organized by responsibility (Controller, Model, Service, etc.)
-- Not accessible from the web
-
-### **config/** (PRIVATE)
-- Configuration files
-- Database credentials, API keys, app settings
-- `.env` file for environment-specific configuration
-- Never committed sensitive values (use `.env.example`)
-
-### **database/** (PRIVATE)
-- Database migrations, seeds, schema definitions
-- Version-controlled database structure
-
-### **tests/** (PRIVATE)
-- PHPUnit tests
-- Organized by test type (Unit, Integration, Functional)
-- Mirror the `src/` structure
-
-### **vendor/** (PRIVATE)
-- Composer dependencies
-- Auto-generated, excluded from version control
-- Contains `autoload.php` for autoloading
-
-### **bin/** (PRIVATE)
-- Executable scripts and CLI commands
-- Make scripts executable: `chmod +x bin/*`
-
-### **var/** (PRIVATE)
-- Runtime-generated files
-- cache/, logs/, tmp/
-- Typically .gitignored (except .gitkeep files)
-- Needs write permissions
-
-### **docs/** (PRIVATE)
-- Project documentation
-- API docs, guides, architecture decisions
-
-### **scripts/** (PRIVATE)
-- Build, deployment, maintenance scripts
-- Not part of the application runtime
-
-### **resources/** (PRIVATE)
-- Non-PHP application resources
-- Templates, translations, email layouts
-
-## Migration from Current Structure
-
-Your current structure → Recommended structure:
-
-```
-Current → Recommended
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-index.php → public/index.php
-memoire.php → public/memoire.php OR src/Controller/
-search.php → public/search.php OR src/Controller/
-assets/ → public/assets/
-inc/ → src/ OR config/
-admin/ → src/Admin/ OR public/admin/
-database/ → database/ (keep as-is)
-tests/ → tests/ (keep as-is)
-vendor/ → vendor/ (keep as-is)
-lib/ → lib/ OR src/
-docs/ → docs/ (keep as-is)
-scripts/ → scripts/ (keep as-is)
-nginx/ → scripts/nginx/ OR config/nginx/
-```
-
-## Security Best Practices
-
-1. **DocumentRoot = public/**
- - Configure web server to serve only from `public/`
- - All other directories are above DocumentRoot
-
-2. **Sensitive Files**
- - Keep `.env`, config files outside `public/`
- - Never commit passwords, API keys
- - Use `.env.example` for templates
-
-3. **Permissions**
- ```bash
- # Private directories (not writable by web server)
- chmod 755 src/ config/ database/ tests/
-
- # Writable by web server
- chmod 775 var/cache/ var/logs/ var/tmp/
- ```
-
-4. **.gitignore**
- ```
- /vendor/
- /var/cache/*
- /var/logs/*
- /var/tmp/*
- /.env
- composer.lock
- ```
-
-## Web Server Configuration
-
-### Nginx
-```nginx
-server {
- root /path/to/posterg-website/public;
- index index.php;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location ~ \.php$ {
- fastcgi_pass unix:/var/run/php/php-fpm.sock;
- fastcgi_index index.php;
- include fastcgi_params;
- }
-}
-```
-
-### Apache (.htaccess in public/)
-```apache
-
- RewriteEngine On
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteRule ^ index.php [L]
-
-```
-
-## Composer Configuration
-
-Update `composer.json` to use PSR-4 autoloading:
-
-```json
-{
- "autoload": {
- "psr-4": {
- "App\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Tests\\": "tests/"
- }
- }
-}
-```
-
-## Next Steps
-
-1. Create `public/` directory
-2. Move web-accessible files to `public/`
-3. Organize classes into `src/` with namespaces
-4. Move configuration to `config/`
-5. Update web server DocumentRoot
-6. Update paths in application code
-7. Run `composer dump-autoload`
-8. Test the application
-
-## References
-
-- [Standard PHP Package Skeleton](https://github.com/php-pds/skeleton)
-- [PSR-4 Autoloading](https://www.php-fig.org/psr/psr-4/)
-- [Composer Documentation](https://getcomposer.org/doc/)
diff --git a/docs/LIVE_RELOAD_SETUP.md b/docs/LIVE_RELOAD_SETUP.md
deleted file mode 100644
index 8a06301..0000000
--- a/docs/LIVE_RELOAD_SETUP.md
+++ /dev/null
@@ -1,297 +0,0 @@
-# Live Reload Setup
-
-Guide to setting up and using live reload for Post-ERG development.
-
-## 🎯 What is Live Reload?
-
-Live reload automatically refreshes your browser when you save files during development. No need to manually hit refresh!
-
-## ✨ How It Works
-
-1. **JavaScript** in the page polls the server for file changes
-2. **PHP backend** checks file modification times
-3. **Browser** automatically refreshes when changes detected
-
-**No browser extension needed!**
-
----
-
-## 🚀 Setup (One Time)
-
-```bash
-just setup
-```
-
-This clones `php-live-reload` into `vendor/php-live-reload/` (which is gitignored).
-
----
-
-## 🏃 Using Live Reload
-
-### Start Server
-
-```bash
-just serve
-```
-
-Output:
-```
-🚀 Starting Post-ERG development server
-========================================
-
-📍 Public site: http://localhost:8000
-📍 Admin panel: http://localhost:8000/admin/
-
-✨ Live reload enabled - browser auto-refreshes on file save!
-
-Press Ctrl+C to stop
-```
-
-### Edit Files
-
-1. Open http://localhost:8000 in your browser
-2. Edit any PHP, CSS, or JS file
-3. Save the file
-4. **Browser automatically refreshes!** ✨
-
-### What Triggers Reload
-
-- Saving `.php` files
-- Saving `.css` files
-- Saving `.js` files
-- Any file change in the project
-
----
-
-## 🔧 How It's Integrated
-
-### In `inc/header.php`
-
-Live reload script is conditionally included only during development:
-
-```php
-
-
-
-
-```
-
-**Result:**
-- ✅ Included when using `php -S` (development server)
-- ❌ NOT included in production (nginx/apache)
-- ❌ NOT deployed to server (vendor/ is gitignored)
-
-### Detection Logic
-
-```php
-php_sapi_name() === 'cli-server' // True when using PHP dev server
-```
-
-This means live reload is automatically enabled/disabled based on environment!
-
----
-
-## 📁 File Structure
-
-```
-vendor/php-live-reload/
-├── php-live-reload/
-│ ├── live-reload.js # JavaScript client
-│ ├── live-reload.php # PHP backend (checks files)
-│ └── config.php # Configuration
-└── README.md
-```
-
----
-
-## 🧪 Testing Live Reload
-
-### Test It Works
-
-1. Start server: `just serve`
-2. Open http://localhost:8000
-3. Open browser console (F12)
-4. Edit `index.php` and save
-5. Watch browser auto-refresh!
-
-You'll see in console:
-```javascript
-GET /vendor/php-live-reload/php-live-reload/live-reload.php
-change detected
-```
-
----
-
-## ⚙️ Configuration
-
-### Polling Interval
-
-Default: Checks every ~1-2 seconds
-
-To change, edit `vendor/php-live-reload/php-live-reload/config.php`:
-
-```php
-define('MIN_DELAY', 1000); // Minimum milliseconds between checks
-```
-
-### File Watching
-
-By default, watches all files in project directory.
-
-To exclude paths, edit config:
-
-```php
-$exclude = [
- 'vendor',
- '.git',
- 'node_modules',
- 'cache'
-];
-```
-
----
-
-## 🐛 Troubleshooting
-
-### Live Reload Not Working
-
-**1. Check vendor directory exists:**
-```bash
-ls -la vendor/php-live-reload/
-```
-
-If missing:
-```bash
-just setup
-```
-
-**2. Check script is included in page:**
-```bash
-curl -s http://localhost:8000/ | grep live-reload
-```
-
-Should show:
-```html
-
-```
-
-**3. Check endpoint is accessible:**
-```bash
-curl http://localhost:8000/vendor/php-live-reload/php-live-reload/live-reload.php
-```
-
-Should return JSON:
-```json
-{"time": 10, "changed": false}
-```
-
-**4. Check browser console for errors**
-
-Open browser console (F12) and look for:
-- WebSocket errors
-- Network errors to `/vendor/php-live-reload/`
-
-### Script Not Loading
-
-**Make sure you're using dev server:**
-```bash
-just serve
-```
-
-NOT production (nginx/apache).
-
-**Check PHP detection:**
-```bash
-php -r "echo php_sapi_name();"
-```
-
-When using `just serve`, should output: `cli-server`
-
-### Changes Not Detected
-
-**Check polling is working:**
-
-Open browser console, you should see repeated requests to:
-```
-/vendor/php-live-reload/php-live-reload/live-reload.php
-```
-
-If not, check JavaScript loaded:
-```bash
-curl -I http://localhost:8000/vendor/php-live-reload/php-live-reload/live-reload.js
-```
-
-Should return `200 OK`.
-
----
-
-## 🚫 Production Behavior
-
-### Automatically Disabled
-
-Live reload is **automatically disabled** in production because:
-
-1. **`php_sapi_name()` check**: Only true with PHP dev server
-2. **vendor/ gitignored**: Not deployed to server
-3. **nginx serves files**: Different SAPI, condition false
-
-### Verification
-
-On production server:
-```bash
-curl https://posterg.erg.be/ | grep live-reload
-```
-
-Should return nothing (script not included).
-
----
-
-## 💡 Tips
-
-### Multiple Browser Windows
-
-Open multiple tabs/windows - they all get live reload!
-
-```
-http://localhost:8000/ # Homepage
-http://localhost:8000/admin/ # Admin panel
-http://localhost:8000/memoire.php?id=13 # Thesis page
-```
-
-All will auto-refresh on file changes.
-
-### Faster Development
-
-With live reload:
-1. ✅ Edit code
-2. ✅ Save
-3. ✅ Browser refreshes
-4. ✅ See changes instantly!
-
-No more:
-1. ❌ Edit code
-2. ❌ Save
-3. ❌ Switch to browser
-4. ❌ Hit F5
-5. ❌ Switch back to editor
-
-**Saves you seconds on every change!**
-
----
-
-## 📚 More Information
-
-- GitHub: https://github.com/ryantate13/php-live-reload
-- Alternative: https://github.com/guard/guard-livereload
-
----
-
-## ✅ Quick Reference
-
-| Command | Description |
-|---------|-------------|
-| `just setup` | Install live reload (one time) |
-| `just serve` | Start server with live reload |
-| `just stop` | Stop server |
-
-**To use:** `just serve` and edit files - browser auto-refreshes! ✨
diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md
deleted file mode 100644
index 6ec85e1..0000000
--- a/docs/MIGRATION.md
+++ /dev/null
@@ -1,357 +0,0 @@
-# Migration from YAML to SQLite
-
-## Overview
-
-The Post-ERG thesis submission form has been completely overhauled to use a SQLite database instead of flat YAML files. This provides better data integrity, querying capabilities, and prepares the system for a full-featured web application.
-
-## What Changed
-
-### Database Implementation
-
-**Before:** Form data was saved as individual YAML files in `data/yaml/`, with file uploads scattered in `data/content/` and `data/cover/`.
-
-**After:** All thesis data is now stored in a relational SQLite database (`../db/posterg.db`) with proper normalization and foreign key relationships.
-
-### New Architecture
-
-```
-Form Submission Flow:
-1. User fills out enhanced form (index.php)
-2. Form validates input and begins database transaction
-3. Creates/links: author, thesis, supervisors, keywords, languages, formats
-4. Uploads files with random names for security
-5. Records file metadata in database
-6. Commits transaction (all-or-nothing)
-7. Redirects to confirmation page showing database data
-```
-
-### Database Schema Highlights
-
-- **19 tables** including junction tables and views
-- **Normalized structure** (3rd Normal Form)
-- **Automatic timestamps** via triggers
-- **Cascade deletes** for referential integrity
-- **Predefined lookup tables** for orientations, AP programs, finalities, etc.
-- **Views** for simplified querying (v_theses_full, v_theses_public)
-
-## New Files
-
-### `Database.php`
-Database helper class providing:
-- PDO connection with error handling
-- Transaction management
-- Find-or-create methods for entities
-- Prepared statement helpers
-- Lookup methods for all reference data
-
-**Key Methods:**
-```php
-$db = new Database();
-$authorId = $db->findOrCreateAuthor($name, $email);
-$keywordId = $db->findOrCreateKeyword($keyword);
-$orientations = $db->getAllOrientations();
-$thesis = $db->getThesis($id);
-```
-
-## Modified Files
-
-### `index.php`
-**Enhancements:**
-- Dynamically loads form options from database
-- Added required fields per schema:
- - Subtitle (optional)
- - Synopsis (~200 words, required)
- - Finality (Approfondi/Enseignement/Spécialisé)
- - Languages (multiple selection with checkboxes)
- - Formats (multiple selection with checkboxes)
-- Better form organization with sections
-- Improved accessibility (proper labels, IDs)
-
-**New Form Fields:**
-| Field | Type | Required | Notes |
-|-------|------|----------|-------|
-| Subtitle | Text | No | New field |
-| Synopsis | Textarea | Yes | ~200 words |
-| Finality | Select | Yes | From finality_types table |
-| Languages | Checkboxes | Yes | Multiple selection |
-| Formats | Checkboxes | No | Multiple selection |
-
-### `formulaire.php`
-**Complete rewrite** with:
-
-1. **Transaction-Based Processing:**
- - `BEGIN TRANSACTION` at start
- - All insertions in single transaction
- - `COMMIT` on success or `ROLLBACK` on error
- - Ensures data consistency
-
-2. **Prepared Statements:**
- - All SQL queries use PDO prepared statements
- - Protection against SQL injection
- - Parameter binding for all user input
-
-3. **Entity Creation:**
- - Finds or creates authors (by name)
- - Finds or creates supervisors (by name)
- - Finds or creates keywords (by text)
- - Links all entities via junction tables
-
-4. **Identifier Generation:**
- - Format: `YYYY-NNN` (e.g., "2026-001")
- - Automatically increments per year
- - Unique constraint in database
-
-5. **File Handling:**
- - Random cryptographic filenames (32 hex chars)
- - Organized by year and identifier: `data/theses/YYYY/YYYY-NNN/`
- - Cover images separate: `data/covers/`
- - Metadata stored in `thesis_files` table
-
-6. **Validation:**
- - Year range: 2000 to current year + 1
- - Max 10 keywords enforced
- - At least one language required
- - URL format validation
- - File type and size validation
-
-### `thanks.php`
-**Complete redesign:**
-
-- Reads from database using thesis ID
-- Displays data from `v_theses_full` view
-- Shows all relationships: authors, supervisors, keywords, languages, formats
-- Lists uploaded files with metadata (type, size, date)
-- Responsive CSS grid layout
-- Publication status indicator
-
-**Security:**
-- Validates thesis ID (integer only)
-- Uses prepared statements
-- No path traversal vulnerability
-- Error messages don't expose system details
-
-## Database Files
-
-### `../db/posterg.db`
-Initialized SQLite database with:
-- 19 tables (11 core, 5 junction, 3 reference)
-- 2 views (v_theses_full, v_theses_public)
-- Predefined data:
- - 15 orientations
- - 4 AP programs
- - 3 finality types
- - 2 languages (French, English)
- - 7 format types
- - 3 access types
- - 4 static pages
-
-### Schema Documentation
-See `../db/README.md` and `../db/SETUP.md` for complete documentation.
-
-## Security Improvements Retained
-
-All security improvements from the previous commit are preserved:
-
-✅ CSRF protection with session tokens
-✅ Input validation and sanitization
-✅ Prepared statements (SQL injection protection)
-✅ Random filenames for uploads
-✅ File type and size validation
-✅ MIME type checking
-✅ Error logging without exposing paths
-✅ Path traversal protection
-
-## Data Mapping
-
-### YAML to Database Mapping
-
-| Old YAML Field | New Database Location | Notes |
-|----------------|----------------------|-------|
-| `auteurice` | `authors.name` | Normalized, reusable |
-| `email` | `authors.email` | Now in authors table |
-| `année` | `theses.year` | Integer field |
-| `titre` | `theses.title` | Required |
-| - | `theses.subtitle` | New field |
-| `description` | `theses.synopsis` | Renamed for clarity |
-| `problématique` | (not yet used) | Can be added to schema |
-| `orientation` | `theses.orientation_id` | Foreign key to orientations |
-| `ap` | `theses.ap_program_id` | Foreign key to ap_programs |
-| - | `theses.finality_id` | New field (required) |
-| `promoteurice` | `supervisors.name` + `thesis_supervisors` | Many-to-many |
-| `tag` | `keywords.keyword` + `thesis_keywords` | Many-to-many, max 10 |
-| `lien` | `theses.baiu_link` | URL validation |
-| `files` | `thesis_files` table | Full metadata |
-| `couverture` | (stored as file, not in DB yet) | Could add cover_path column |
-
-## Migration Path for Existing Data
-
-If you have existing YAML files to import:
-
-1. **Parse YAML files:**
- ```php
- $yamlFiles = glob('data/yaml/*.yaml');
- foreach ($yamlFiles as $file) {
- $data = Yaml::parseFile($file);
- // ...
- }
- ```
-
-2. **Insert into database:**
- ```php
- $db->beginTransaction();
- try {
- $authorId = $db->findOrCreateAuthor($data['auteurice'], $data['email']);
- // Insert thesis
- // Link relationships
- $db->commit();
- } catch (Exception $e) {
- $db->rollback();
- }
- ```
-
-3. **Verify data:**
- ```sql
- SELECT COUNT(*) FROM theses;
- SELECT * FROM v_theses_full LIMIT 5;
- ```
-
-## Testing Checklist
-
-Before production deployment:
-
-- [ ] Form loads without errors
-- [ ] All dropdown options populate from database
-- [ ] Form submission creates thesis record
-- [ ] Author is created or found correctly
-- [ ] Supervisors linked properly
-- [ ] Keywords created and linked (test max 10)
-- [ ] Languages required (test validation)
-- [ ] Formats optional (test multiple selection)
-- [ ] Files upload successfully
-- [ ] File metadata recorded in database
-- [ ] Thanks page displays all data correctly
-- [ ] Transaction rollback works on error
-- [ ] CSRF token validated
-- [ ] Invalid data rejected (year, URL, etc.)
-
-## Known Limitations
-
-1. **No cover_path column:** Cover images uploaded but path not stored in `theses` table (can be added)
-2. **No problématique field:** Old field not yet in schema (can be added to `theses.remarks` or new column)
-3. **File type detection:** Basic (by extension), could be enhanced
-4. **No duplicate detection:** Same thesis can be submitted multiple times
-5. **No edit capability:** Once submitted, no UI to edit (admin interface needed)
-
-## Next Steps
-
-1. **Initialize production database:**
- ```bash
- cd /path/to/production/db
- sqlite3 posterg.db < schema.sql
- ```
-
-2. **Set permissions:**
- ```bash
- chmod 644 posterg.db
- chown www-data:www-data posterg.db
- ```
-
-3. **Test form submission:**
- - Submit test thesis
- - Verify all fields saved
- - Check file uploads
- - Test thanks page
-
-4. **Import existing data:**
- - Create migration script
- - Parse old YAML files
- - Bulk insert into database
- - Verify integrity
-
-5. **Build admin interface:**
- - CRUD operations for theses
- - User management
- - Approval workflow
- - Bulk operations
-
-6. **Build public website:**
- - Search and filter theses
- - Respect access controls
- - Display thesis details
- - Static pages management
-
-## Compatibility Notes
-
-### PHP Requirements
-- PHP 7.4+ (tested on PHP 8.x)
-- PDO extension with SQLite support
-- Composer for Symfony YAML (still used for potential migration)
-
-### Database
-- SQLite 3.8.0+
-- File-based database (no server needed)
-- Single file: `db/posterg.db`
-
-### Dependencies
-```json
-{
- "require": {
- "symfony/yaml": "^6.2",
- "behat/transliterator": "^1.5"
- }
-}
-```
-
-Note: YAML library retained for potential data migration from old files.
-
-## Backup Strategy
-
-SQLite database is a single file - easy to backup:
-
-```bash
-# Simple copy
-cp db/posterg.db db/backups/posterg_$(date +%Y%m%d).db
-
-# SQL dump (portable)
-sqlite3 db/posterg.db .dump > backups/posterg_$(date +%Y%m%d).sql
-
-# Compressed backup
-tar -czf backups/posterg_$(date +%Y%m%d).tar.gz db/posterg.db data/
-```
-
-Set up automated daily backups via cron.
-
-## Performance Considerations
-
-- **Indexes:** All critical foreign keys and search fields indexed
-- **Views:** Pre-computed joins for common queries
-- **Transactions:** Ensure atomicity without locking issues
-- **File I/O:** Random filenames prevent directory listing overhead
-
-For large datasets (1000+ theses):
-- Consider WAL mode: `PRAGMA journal_mode=WAL;`
-- Optimize with `ANALYZE;` periodically
-- Monitor database size and `VACUUM` if needed
-
-## Rollback Plan
-
-If issues arise, you can roll back to YAML-based system:
-
-1. Use previous jj commit: `jj checkout `
-2. Old YAML files in `data/yaml/` still intact
-3. Database changes don't affect old YAML code
-4. Can run both systems in parallel during transition
-
-## Support
-
-For questions or issues:
-- Schema documentation: `db/README.md`
-- Setup guide: `db/SETUP.md`
-- Security details: `SECURITY.md`
-- Technical specs: `db/posterg_fiche-technique.md`
-
----
-
-**Migration completed:** 2026-01-27
-**Database version:** 1.0
-**Form version:** 2.0 (SQLite)
diff --git a/docs/MIGRATION_CHECKLIST.md b/docs/MIGRATION_CHECKLIST.md
deleted file mode 100644
index 18d0a82..0000000
--- a/docs/MIGRATION_CHECKLIST.md
+++ /dev/null
@@ -1,381 +0,0 @@
-# Migration Checklist - Public Directory Structure
-
-Quick reference for migrating from current flat structure to secure public/ structure.
-
-## 📋 Summary of Required Changes
-
-### 1. Dev Server (justfile) ⚡
-**Line 51** - Change from:
-```just
-@php -S 127.0.0.1:8000
-```
-To:
-```just
-@php -S 127.0.0.1:8000 -t public/
-```
-
-### 2. Deployment (justfile) 📤
-**Lines 56-75** - Replace entire `deploy` recipe with two-step deployment:
-- Deploy app to `/var/www/posterg/` (not `/var/www/html/`)
-- Nginx serves from `/var/www/posterg/public/`
-
-See `DEPLOYMENT_MIGRATION.md` for complete updated recipe.
-
-### 3. Nginx Configuration 🔧
-**nginx/posterg.conf line 14** - Change from:
-```nginx
-root /var/www/html;
-```
-To:
-```nginx
-root /var/www/posterg/public;
-```
-
-**Also update admin location** (line 58) - Change from:
-```nginx
-location ^~ /formulaire/ {
-```
-To:
-```nginx
-location ^~ /admin/ {
-```
-(Since you're moving admin/ to public/admin/)
-
----
-
-## 🚀 Quick Migration (Local Dev)
-
-```bash
-# 1. Update justfile serve command
-sed -i 's/@php -S 127.0.0.1:8000/@php -S 127.0.0.1:8000 -t public\//' justfile
-
-# 2. Test new dev server
-just serve
-# Visit http://localhost:8000
-# Verify http://localhost:8000/storage/test.db returns 404
-
-# 3. If it works, you're ready for production migration
-```
-
----
-
-## 📁 File Movements (Do This After Testing)
-
-```bash
-# Create new structure
-mkdir -p public/{admin,assets}
-mkdir -p src config var/{cache,logs,tmp}
-
-# Move public files
-mv index.php search.php memoire.php public/
-mv admin/* public/admin/ && rmdir admin
-mv assets/* public/assets/ && rmdir assets
-
-# Move private files
-mv inc/* config/ && rmdir inc
-# OR if inc/ contains classes:
-# mv inc/* src/ && rmdir inc
-
-# Keep these as-is
-# database/ (already private)
-# vendor/ (already private)
-# tests/ (already private)
-# lib/ (decide if it goes to src/lib or stays)
-```
-
----
-
-## ⚠️ Critical Changes Required
-
-### In nginx/posterg.conf:
-
-1. **Line 14** - DocumentRoot
-```nginx
-# BEFORE
-root /var/www/html;
-
-# AFTER
-root /var/www/posterg/public;
-```
-
-2. **Line 58-76** - Admin location (already at `/formulaire/`, might want `/admin/`)
-```nginx
-# BEFORE
-location ^~ /formulaire/ {
- auth_basic "Admin Access - Post-ERG";
- auth_basic_user_file /etc/nginx/.htpasswd-posterg;
- # ... rest of config
-}
-
-# AFTER (if renaming to /admin/)
-location ^~ /admin/ {
- auth_basic "Admin Access - Post-ERG";
- auth_basic_user_file /etc/nginx/.htpasswd-posterg;
- # ... rest of config
-}
-```
-
-3. **Remove/update deny rules** (lines 48-60) - These become redundant!
-```nginx
-# BEFORE - needed because everything in DocumentRoot
-location ^~ /storage/ { deny all; }
-location ^~ /shared/ { deny all; }
-location ^~ /data/ { deny all; }
-
-# AFTER - can remove! They're already outside public/
-# But keep as defense-in-depth:
-location ^~ /storage/ { deny all; } # Will never match, but safe
-```
-
-### In justfile:
-
-**Complete replacement for lines 40-76:**
-
-```just
-[group('dev')]
-serve:
- @echo "🚀 Starting Post-ERG development server"
- @echo "========================================"
- @echo ""
- @echo "📍 Public site: http://localhost:8000"
- @echo "📍 Admin panel: http://localhost:8000/admin/"
- @echo ""
- @echo "🔒 Serving from public/ directory (matches production)"
- @if [ -d "vendor/php-live-reload" ]; then \
- echo "✨ Live reload enabled"; \
- else \
- echo "💡 Tip: Run 'just setup' to enable live reload"; \
- fi
- @echo ""
- @echo "Press Ctrl+C to stop"
- @echo ""
- @php -S 127.0.0.1:8000 -t public/
-
-[group('deploy')]
-deploy:
- @echo "📤 Deploying Post-ERG complete site"
- @echo "===================================="
- @echo ""
- @echo "Deploying to /var/www/posterg/..."
- rsync -vur --progress \
- --chown="www-data:posterg" \
- --exclude 'vendor' \
- --exclude 'tests' \
- --exclude 'test.db' \
- --exclude '*.md' \
- --exclude '.git*' \
- --exclude '.jj' \
- --exclude '.DS_Store' \
- --exclude 'justfile*' \
- --exclude 'setup-dev.sh' \
- --exclude 'database/backup_*' \
- --exclude 'database/fixtures' \
- --exclude 'var/cache/*' \
- --exclude 'var/logs/*' \
- ./ posterg:/var/www/posterg/
- @echo ""
- @echo "Setting up directories and permissions..."
- ssh posterg "cd /var/www/posterg && \
- mkdir -p var/{cache,logs,tmp} && \
- chown -R www-data:posterg var/ database/ && \
- chmod -R 775 var/ database/ && \
- chmod 660 database/*.db"
- @echo ""
- @echo "✅ Deployment complete!"
- @echo ""
- @echo "🔍 Verify:"
- @echo " • Public: https://posterg.erg.be/"
- @echo " • Admin: https://posterg.erg.be/admin/"
-
-[group('deploy')]
-test-deploy:
- @echo "⚠️ Deploying test database"
- ssh posterg "mkdir -p /var/www/posterg/database"
- rsync -vur --progress ./storage/test.db posterg:/var/www/posterg/storage/
- ssh posterg "chown www-data:posterg /var/www/posterg/storage/test.db && \
- chmod 660 /var/www/posterg/storage/test.db"
- @echo "✅ Test database deployed"
-```
-
----
-
-## 🧪 Testing Steps
-
-### 1. Test Local Dev Server
-```bash
-# Start server with new -t public/ flag
-just serve
-
-# In another terminal:
-curl http://localhost:8000/ # ✅ Should work
-curl http://localhost:8000/admin/ # ✅ Should work (after moving)
-curl http://localhost:8000/storage/test.db # ❌ Should 404
-curl http://localhost:8000/config/ # ❌ Should 404
-curl http://localhost:8000/vendor/ # ❌ Should 404
-```
-
-### 2. Test After File Migration
-```bash
-# After moving files to public/
-just serve
-
-# Test again
-curl http://localhost:8000/ # ✅ index.php serves
-curl http://localhost:8000/search.php # ✅ works
-curl http://localhost:8000/admin/ # ✅ works
-curl http://localhost:8000/assets/css/style.css # ✅ works
-
-# Verify old paths don't work
-curl http://localhost:8000/../storage/test.db # ❌ 404
-curl http://localhost:8000/../config/ # ❌ 404
-```
-
-### 3. Test Production Deployment
-```bash
-# After deploying to server
-just server-status
-
-# Manual checks
-curl -I https://posterg.erg.be/
-curl -I https://posterg.erg.be/admin/
-curl -I https://posterg.erg.be/storage/test.db # Must be 404!
-```
-
----
-
-## 📝 PHP Path Updates Needed
-
-After moving to public/, update PHP includes:
-
-**Before (from root):**
-```php
- paths-audit.txt
-
-# Review paths-audit.txt and update paths
-cat paths-audit.txt
-```
-
-See **DEPLOYMENT_MIGRATION.md** for complete implementation details.
diff --git a/docs/MIGRATION_COMPLETE.md b/docs/MIGRATION_COMPLETE.md
deleted file mode 100644
index d04d93f..0000000
--- a/docs/MIGRATION_COMPLETE.md
+++ /dev/null
@@ -1,214 +0,0 @@
-# ✅ Migration to public/ Directory Structure - COMPLETE
-
-## 📊 Summary of Changes
-
-### Directory Structure Created
-```
-posterg-website/
-├── config/ # ✅ NEW - Configuration files
-│ └── bootstrap.php # Central path management
-├── public/ # ✅ NEW - DocumentRoot (web-accessible)
-│ ├── admin/ # Moved from /admin/
-│ ├── assets/ # Moved from /assets/
-│ ├── index.php # Moved from /index.php
-│ ├── search.php # Moved from /search.php
-│ └── memoire.php # Moved from /memoire.php
-├── resources/ # ✅ NEW - Application resources
-│ └── views/ # Moved from /inc/
-│ ├── header.php
-│ └── footer.php
-├── var/ # ✅ NEW - Runtime files
-│ ├── cache/
-│ ├── logs/
-│ └── tmp/
-├── database/ # ✅ KEPT - Now private
-├── lib/ # ✅ KEPT - Now private
-├── vendor/ # ✅ KEPT - Now private
-└── tests/ # ✅ KEPT - Now private
-```
-
-### Files Modified
-
-**1. config/bootstrap.php** (NEW)
-- Central path configuration
-- Defines APP_ROOT, PUBLIC_ROOT, DATABASE_PATH, etc.
-- Helper functions: view(), getDatabase()
-- Environment detection (dev vs production)
-- Error handling configuration
-
-**2. public/*.php** (3 files updated)
-- index.php: Uses bootstrap, updated require paths
-- search.php: Uses bootstrap, updated require paths
-- memoire.php: Uses bootstrap, updated require paths
-- All now use view() helper for header/footer
-
-**3. public/admin/*.php** (7 files updated)
-- add.php, edit.php, formulaire.php, import.php
-- index.php, publish.php, thanks.php
-- All updated to use ../../ paths for lib access
-- Bootstrap added where needed
-
-**4. justfile** (Updated)
-- Dev server: `php -S 127.0.0.1:8000 -t public/`
-- Deploy: Now deploys to `/var/www/posterg/`
-- Database deploy: Updated paths to `/var/www/posterg/`
-- Nginx deploy: Checks for correct DocumentRoot
-
-**5. nginx/posterg.conf** (Updated)
-- DocumentRoot: `/var/www/html` → `/var/www/posterg/public`
-- Admin location: `/formulaire/` → `/admin/`
-
-**6. .gitignore** (Updated)
-- Added var/ directory patterns
-- Keeps .gitkeep files, ignores contents
-
-### Security Improvements
-
-**Before:**
-- ❌ All files in DocumentRoot (/var/www/html/)
-- ❌ Database accessible at /storage/test.db
-- ❌ Config files accessible
-- ❌ Dev server exposed everything
-- ❌ Relied on nginx deny rules
-
-**After:**
-- ✅ Only public/ in DocumentRoot
-- ✅ Database physically outside web root
-- ✅ Config files physically private
-- ✅ Dev server matches production security
-- ✅ Physical separation = secure by default
-
-## 🧪 Testing
-
-### Local Development
-```bash
-# Start dev server
-just serve
-
-# Test in browser:
-# - http://localhost:8000/ → Should work
-# - http://localhost:8000/admin/ → Should work
-# - http://localhost:8000/storage/test.db → Should 404 ✅
-# - http://localhost:8000/config/ → Should 404 ✅
-# - http://localhost:8000/../storage/test.db → Should 404 ✅
-```
-
-### Security Verification
-```bash
-# These should all return 404:
-curl http://localhost:8000/storage/test.db
-curl http://localhost:8000/config/bootstrap.php
-curl http://localhost:8000/vendor/autoload.php
-curl http://localhost:8000/../storage/test.db
-curl http://localhost:8000/lib/Database.php
-```
-
-### Production Deployment
-
-**BEFORE deploying to production:**
-
-1. **Update nginx config on server:**
- ```bash
- # Edit /etc/nginx/sites-available/posterg
- # Change: root /var/www/html;
- # To: root /var/www/posterg/public;
- ```
-
-2. **Create new directory on server:**
- ```bash
- ssh posterg "sudo mkdir -p /var/www/posterg"
- ```
-
-3. **Deploy application:**
- ```bash
- just deploy
- ```
-
-4. **Deploy nginx config:**
- ```bash
- just deploy-nginx
- # Then on server:
- ssh posterg
- sudo bash /tmp/deploy-production.sh
- sudo systemctl reload nginx
- ```
-
-5. **Verify:**
- ```bash
- just server-status
- curl -I https://posterg.erg.be/
- curl -I https://posterg.erg.be/admin/
- curl -I https://posterg.erg.be/storage/test.db # Must 404!
- ```
-
-## 📝 Path Reference
-
-### From public/*.php files:
-```php
- 'Title']); // Template
-```
-
-### From public/admin/*.php files:
-```php
-
-
-# Or abandon current changes
-jj abandon @
-```
-
-## 📚 Documentation
-
-See also:
-- `DIRECTORY_STRUCTURE.md` - Full structure reference
-- `DEPLOYMENT_MIGRATION.md` - Detailed migration guide
-- `MIGRATION_CHECKLIST.md` - Quick checklist
-
-## ✨ Benefits Achieved
-
-1. **Security**: Private files physically separated from public
-2. **Standards**: Follows PHP-FIG and Standard PHP Package Skeleton
-3. **Development**: Dev server matches production security
-4. **Maintainability**: Clear separation of concerns
-5. **Portability**: Path constants make relocation easy
-6. **Best Practices**: Industry-standard directory structure
diff --git a/docs/MIGRATION_GUIDE.md b/docs/MIGRATION_GUIDE.md
deleted file mode 100644
index 22821b8..0000000
--- a/docs/MIGRATION_GUIDE.md
+++ /dev/null
@@ -1,476 +0,0 @@
-# Repository Restructure Migration Guide
-
-This guide explains how to migrate the Post-ERG repository to a standard idiomatic PHP structure.
-
-## 📋 Overview
-
-### Current Structure
-```
-posterg-website/
-├── apps/
-│ ├── public/ # Public website
-│ └── admin/ # Admin panel
-├── shared/ # Shared PHP libraries
-└── database/ # Database files
-```
-
-### New Structure (Standard PHP)
-```
-posterg-website/
-├── index.php # Public root
-├── *.php # Public PHP files
-├── admin/ # Admin panel
-├── lib/ # Shared libraries (renamed from shared/)
-├── inc/ # Templates (header/footer)
-├── assets/ # Static files
-├── database/ # Database files
-└── vendor/ # Third-party code (gitignored)
-```
-
----
-
-## 🎯 Benefits
-
-✅ **Standard PHP structure** - Follows community conventions
-✅ **Flatter hierarchy** - Easier navigation
-✅ **Simpler paths** - Less `../../` in code
-✅ **Cleaner deployment** - Single rsync command
-✅ **Live reload** - Auto-refresh during development
-
----
-
-## 🚀 Migration Steps
-
-### Step 1: Review the Plan
-
-Read the restructure plan:
-```bash
-cat docs/RESTRUCTURE_PLAN.md
-```
-
-### Step 2: Commit Current State
-
-**Important:** Commit all your current work first!
-
-```bash
-git add -A
-git commit -m "Pre-migration checkpoint"
-```
-
-### Step 3: Run Migration Script
-
-```bash
-./migrate-structure.sh
-```
-
-This will:
-- Move `apps/public/*` to root
-- Move `apps/admin/` to `admin/`
-- Rename `shared/` to `src/`
-- Update all `require` paths automatically
-- Remove `apps/` directory
-- Update `.gitignore`
-
-### Step 4: Test Locally
-
-```bash
-# Setup development environment
-just setup-dev
-
-# Test public site (with live reload!)
-just serve-public
-
-# Test admin panel
-just serve-admin
-```
-
-Visit:
-- http://localhost:8000 - Public site
-- http://localhost:3000 - Admin panel
-
-### Step 5: Verify Changes
-
-```bash
-# Check syntax
-just check-public
-
-# Run database tests
-just stats-public
-
-# View structure
-tree -L 2 -I 'node_modules|.git|vendor'
-```
-
-### Step 6: Update Justfile
-
-```bash
-# Backup old justfile
-mv justfile justfile.old
-
-# Use new justfile
-mv justfile.new justfile
-```
-
-### Step 7: Commit Migration
-
-```bash
-git add -A
-git commit -m "Restructure to idiomatic PHP layout
-
-- Moved apps/public to root
-- Moved apps/admin to admin/
-- Renamed shared/ to lib/
-- Added php-live-reload for local dev
-- Updated all require paths
-- Simplified deployment"
-```
-
-### Step 8: Deploy to Production
-
-```bash
-# Deploy everything
-just deploy
-
-# Or deploy separately
-just deploy-public
-just deploy-admin
-```
-
----
-
-## 📝 What Changed
-
-### File Movements
-
-| Old Path | New Path |
-|----------|----------|
-| `apps/public/index.php` | `index.php` |
-| `apps/public/memoire.php` | `memoire.php` |
-| `apps/public/assets/` | `assets/` |
-| `apps/public/inc/` | `inc/` |
-| `apps/admin/` | `admin/` |
-| `shared/Database.php` | `src/Database.php` |
-| `shared/config.php` | `src/config.php` |
-| `shared/cache/` | `src/cache/` |
-
-### Path Updates
-
-All PHP files automatically updated:
-
-**Root files:**
-```php
-// Before
-require_once __DIR__ . '/shared/Database.php';
-
-// After
-require_once __DIR__ . '/lib/Database.php';
-```
-
-**Admin files:**
-```php
-// Before
-require_once __DIR__ . '/../../shared/Database.php';
-
-// After
-require_once __DIR__ . '/../lib/Database.php';
-```
-
-**Config file:**
-```php
-// Before
-define('DB_ROOT', __DIR__ . '/..');
-
-// After (stays the same)
-define('DB_ROOT', __DIR__ . '/..');
-```
-
-### Justfile Changes
-
-**Before:**
-```bash
-just serve-public # Basic PHP server
-```
-
-**After:**
-```bash
-just setup-dev # One-time: Install php-live-reload
-just serve-public # PHP server with live reload!
-```
-
-**Before:**
-```bash
-# Deploy in multiple steps
-rsync apps/public/ posterg:/var/www/html/
-rsync apps/admin/ posterg:/var/www/html/formulaire/
-rsync shared/ posterg:/var/www/html/shared/
-```
-
-**After:**
-```bash
-# Deploy in one command
-just deploy
-```
-
----
-
-## 🔄 PHP Live Reload
-
-### What It Does
-
-Automatically refreshes your browser when you save PHP files!
-
-### Setup (One Time)
-
-```bash
-just setup-dev
-```
-
-This clones https://github.com/ryantate13/php-live-reload to `vendor/php-live-reload/` (gitignored).
-
-### Usage
-
-```bash
-# Start with live reload
-just serve-public # or serve-admin
-
-# Edit PHP files
-# Browser auto-refreshes on save! 🎉
-```
-
-### How It Works
-
-- Monitors PHP files for changes
-- Sends reload signal via WebSocket
-- Browser reloads automatically
-- No browser extension needed
-- Only for local development
-- Never deployed to production
-
----
-
-## 🧪 Testing
-
-### Before Deploying
-
-1. **Syntax check:**
- ```bash
- just check-public
- ```
-
-2. **Test database:**
- ```bash
- just stats-public
- ```
-
-3. **Test public site:**
- ```bash
- just serve-public
- # Visit http://localhost:8000
- ```
-
-4. **Test admin:**
- ```bash
- just serve-admin
- # Visit http://localhost:3000
- ```
-
-5. **Check file permissions:**
- ```bash
- ls -la | head -n 20
- ls -la admin/ | head -n 20
- ls -la lib/
- ```
-
-### After Deploying
-
-1. **Test public site:**
- ```bash
- curl -I https://posterg.erg.be/
- ```
-
-2. **Test CSS loading:**
- ```bash
- curl -I https://posterg.erg.be/assets/posterg.css
- ```
-
-3. **Test admin:**
- ```bash
- curl -I https://posterg.erg.be/admin/
- ```
-
----
-
-## 🔙 Rollback (If Needed)
-
-If something goes wrong:
-
-```bash
-# Revert the migration
-git reset --hard HEAD~1
-
-# Or restore from backup
-git checkout HEAD~1 -- .
-```
-
----
-
-## 📚 New Directory Structure
-
-```
-posterg-website/
-├── index.php # Public site root
-├── memoire.php # Thesis detail page
-├── search.php # Search page
-├── apropos.php # About page
-├── contact.php # Contact page
-├── licences.php # Licenses page
-├── test_db.php # Database test script
-│
-├── assets/ # Static files
-│ ├── posterg.css # Main CSS
-│ ├── normalize.css # CSS reset
-│ ├── fonts/ # Custom fonts
-│ └── icons.svg # Icon set
-│
-├── inc/ # Page templates
-│ ├── header.php # Site header
-│ └── footer.php # Site footer
-│
-├── lib/ # Shared libraries (was shared/)
-│ ├── Database.php # Database class
-│ ├── RateLimit.php # Rate limiting
-│ ├── config.php # Configuration
-│ └── cache/ # Cache files
-│
-├── admin/ # Admin panel (was apps/admin/)
-│ ├── index.php # Admin dashboard
-│ ├── list.php # Thesis list
-│ ├── edit.php # Edit thesis
-│ ├── formulaire.php # Add thesis
-│ ├── import.php # Import tool
-│ └── data/ # Upload directories
-│
-├── database/ # Database files & schema
-│ ├── schema.sql # Database schema
-│ ├── test.db # Test database
-│ ├── fixtures/ # Test data generators
-│ └── *.md # Documentation
-│
-├── vendor/ # Third-party code (gitignored)
-│ └── php-live-reload/ # Live reload tool
-│
-├── nginx/ # Server configuration
-├── docs/ # Documentation
-├── tests/ # Tests (future)
-│
-├── justfile # Task runner
-├── .gitignore # Git ignore rules
-└── README.md # Project readme
-```
-
----
-
-## ❓ FAQ
-
-### Q: Will the migration break the deployed site?
-
-**A:** No. The migration only affects your local repository. Deploy only after testing locally.
-
-### Q: Do I need to update the database?
-
-**A:** No. The database structure doesn't change. Only file paths change.
-
-### Q: What about nginx configuration?
-
-**A:** Nginx config doesn't need to change. It still serves from `/var/www/html/`.
-
-### Q: Will git history be preserved?
-
-**A:** Yes. Git tracks file movements. Use `git log --follow filename.php` to see history.
-
-### Q: Can I undo the migration?
-
-**A:** Yes. Use `git reset --hard HEAD~1` before committing.
-
-### Q: Does php-live-reload work on all platforms?
-
-**A:** Yes. Works on Linux, macOS, and Windows (with PHP installed).
-
-### Q: Will php-live-reload be deployed?
-
-**A:** No. It's in `vendor/` which is gitignored and excluded from deployment.
-
----
-
-## 🆘 Troubleshooting
-
-### Migration script fails
-
-**Check you're in the repo root:**
-```bash
-pwd
-ls -la apps shared
-```
-
-**Make script executable:**
-```bash
-chmod +x migrate-structure.sh
-```
-
-### PHP can't find lib/ files
-
-**Check paths were updated:**
-```bash
-grep -r "require.*lib/" . --include="*.php" | head -n 5
-```
-
-**Manually fix a file:**
-```bash
-# Edit the file and change:
-require_once __DIR__ . '/shared/Database.php';
-# To:
-require_once __DIR__ . '/lib/Database.php';
-```
-
-### Live reload doesn't work
-
-**Check vendor directory:**
-```bash
-ls -la vendor/php-live-reload/
-```
-
-**Re-run setup:**
-```bash
-just setup-dev
-```
-
-### Site works locally but not on server
-
-**Check file permissions on server:**
-```bash
-ssh posterg "ls -la /var/www/html/ | head -n 20"
-```
-
-**Re-run deployment:**
-```bash
-just deploy
-```
-
----
-
-## 📞 Need Help?
-
-1. **Check the plan:** `cat docs/RESTRUCTURE_PLAN.md`
-2. **Review justfile:** `cat justfile`
-3. **Check git status:** `git status`
-4. **Test locally first:** `just serve-public`
-
----
-
-**Ready to migrate?**
-
-```bash
-./migrate-structure.sh
-```
-
-Good luck! 🚀
diff --git a/docs/QUICK_SCHEMA_REFERENCE.md b/docs/QUICK_SCHEMA_REFERENCE.md
deleted file mode 100644
index 6f9ddb5..0000000
--- a/docs/QUICK_SCHEMA_REFERENCE.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# Database Quick Reference
-
-Quick lookup for the Post-ERG database schema.
-
-## 📊 Table Summary
-
-| Table | Type | Records | Description |
-|-------|------|---------|-------------|
-| `theses` | Core | ~500/year | Main thesis records |
-| `authors` | Core | ~600 | Student/author info |
-| `supervisors` | Core | ~50 | Thesis supervisors |
-| `thesis_authors` | Junction | ~550/year | Thesis ↔ Authors |
-| `thesis_supervisors` | Junction | ~600/year | Thesis ↔ Supervisors |
-| `thesis_languages` | Junction | ~550/year | Thesis ↔ Languages |
-| `thesis_formats` | Junction | ~700/year | Thesis ↔ Formats |
-| `thesis_keywords` | Junction | ~3000/year | Thesis ↔ Keywords |
-| `thesis_files` | Support | ~800/year | File attachments |
-| `orientations` | Lookup | 15 | Art orientations |
-| `ap_programs` | Lookup | 4 | Workshop programs |
-| `finality_types` | Lookup | 3 | Master finalities |
-| `languages` | Lookup | 2+ | Languages |
-| `format_types` | Lookup | 7 | Media formats |
-| `access_types` | Lookup | 3 | Access levels |
-| `license_types` | Lookup | ~10 | Creative Commons |
-| `keywords` | Lookup | ~500+ | Tag system |
-| `pages` | Support | 4 | Static pages |
-
-## 🔑 Key Relationships
-
-```
-theses ──┬── 1:N ──► thesis_authors ──► N:1 ── authors
- ├── 1:N ──► thesis_supervisors ──► N:1 ── supervisors
- ├── 1:N ──► thesis_keywords ──► N:1 ── keywords
- ├── 1:N ──► thesis_languages ──► N:1 ── languages
- ├── 1:N ──► thesis_formats ──► N:1 ── format_types
- ├── 1:N ──► thesis_files
- ├── N:1 ──► orientations
- ├── N:1 ──► ap_programs
- ├── N:1 ──► finality_types
- ├── N:1 ──► access_types
- └── N:1 ──► license_types
-```
-
-## 📝 Core Fields Reference
-
-### `theses` (Main Table)
-
-**Identity:**
-- `id` - Primary key
-- `identifier` - Human-readable ID (e.g., "2025-002")
-
-**Basic Info:**
-- `title` - Thesis title (required)
-- `subtitle` - Optional subtitle
-- `year` - Academic year (required)
-- `is_doctoral` - TFE (0) or Doctoral (1)
-
-**Academic:**
-- `orientation_id` - Art orientation
-- `ap_program_id` - Workshop program
-- `finality_id` - Master finality type
-
-**Content:**
-- `synopsis` - ~200 word summary
-- `context_note` - Jury note (max 150 words)
-- `duration_minutes` - For audio/video
-- `duration_pages` - For written works
-
-**Access:**
-- `access_type_id` - Public/Internal/Restricted
-- `license_id` - Creative Commons, etc.
-
-**Workflow:**
-- `submitted_at` - Student submission
-- `defense_date` - Defense date
-- `is_published` - Public visibility
-- `published_at` - Publication date
-- `jury_points` - Grade (0-20)
-
-## 🏷️ Lookup Values
-
-### Orientations (15)
-Arts Numériques, Dessin, Cinéma d'animation, Installation-Performance, Peinture, Photographie, Sculpture, Vidéographie, Graphisme, Typographie, Design Numérique, Illustration, Bande-Dessinée, Sérigraphie, Gravure
-
-### AP Programs (4)
-- Narration Spéculative
-- Design et Politique du Multiple (DPM)
-- Atelier Pratiques Situées (APS)
-- Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes (LIENS)
-
-### Finality Types (3)
-Approfondi, Enseignement, Spécialisé
-
-### Languages (2+)
-Français, Anglais
-
-### Format Types (7)
-Site web, Audio, Vidéo, Performance, Objet éditorial, Installation, Autre
-
-### Access Types (3)
-- **Libre**: Full access online + library
-- **Interne**: Library only, note online
-- **Interdit**: No access, note only
-
-## 🔍 Common Queries
-
-### Get Published Theses
-```sql
-SELECT * FROM v_theses_public ORDER BY year DESC;
-```
-
-### Get Thesis by ID
-```sql
-SELECT * FROM v_theses_full WHERE id = ?;
-```
-
-### Search by Title
-```sql
-SELECT * FROM v_theses_public
-WHERE title LIKE '%keyword%'
-ORDER BY year DESC;
-```
-
-### Filter by Year
-```sql
-SELECT * FROM v_theses_public
-WHERE year = 2025
-ORDER BY title;
-```
-
-### Filter by Orientation
-```sql
-SELECT t.* FROM theses t
-JOIN orientations o ON t.orientation_id = o.id
-WHERE o.name = 'Arts Numériques'
-AND t.is_published = 1;
-```
-
-### Get Author's Theses
-```sql
-SELECT t.* FROM theses t
-JOIN thesis_authors ta ON t.id = ta.thesis_id
-JOIN authors a ON ta.author_id = a.id
-WHERE a.name LIKE '%name%'
-AND t.is_published = 1;
-```
-
-### Get Keywords for Thesis
-```sql
-SELECT k.keyword FROM keywords k
-JOIN thesis_keywords tk ON k.id = tk.keyword_id
-WHERE tk.thesis_id = ?;
-```
-
-### Count by Year
-```sql
-SELECT year, COUNT(*) as count
-FROM theses
-WHERE is_published = 1
-GROUP BY year
-ORDER BY year DESC;
-```
-
-## 📌 Important Constraints
-
-- **Unique:** `theses.identifier`, `authors.email`, all lookup table names
-- **Required:** `theses.title`, `theses.year`, at least one author
-- **Max:** 10 keywords per thesis
-- **Range:** `jury_points` 0.00 - 20.00
-- **Cascade:** All junction tables DELETE CASCADE
-
-## 🎯 Views
-
-### `v_theses_full`
-Complete thesis data with all relationships (comma-separated).
-
-### `v_theses_public`
-Only published theses (`is_published = 1`).
-
-## 🔧 Making Changes
-
-**Format for change requests:**
-
-```
-Table: [table_name]
-Change: [add/modify/remove]
-Column: [column_name]
-Type: [data_type]
-Reason: [why needed]
-Example: [sample data]
-```
-
-**Example:**
-
-```
-Table: theses
-Change: add
-Column: external_url
-Type: TEXT
-Reason: Link to external project website
-Example: https://example.com/project
-```
-
-## 📚 Full Documentation
-
-See `DATABASE_SPECIFICATION.md` for complete details.
diff --git a/docs/README_SECURE_SEARCH.md b/docs/README_SECURE_SEARCH.md
deleted file mode 100644
index a4b12a9..0000000
--- a/docs/README_SECURE_SEARCH.md
+++ /dev/null
@@ -1,345 +0,0 @@
-# Secure Search Implementation - Complete
-
-## ✅ Implementation Complete
-
-The search feature has been implemented with **production-grade security** including comprehensive input validation, wildcard injection prevention, rate limiting, and pagination controls.
-
----
-
-## Quick Start
-
-### 1. Test Database Setup
-```bash
-cd /home/padlock/dev/posterg-website/front-backend
-php create_test_db.php
-```
-
-### 2. Run Tests
-```bash
-# Functional tests
-php test_search.php
-
-# Security tests
-php test_security_updated.php
-
-# Rate limiting tests
-php test_rate_limit.php
-```
-
-### 3. Access Search Page
-Navigate to: `search.php`
-
----
-
-## Security Features
-
-### 🔒 Protection Against:
-
-| Threat | Protection | Status |
-|--------|-----------|--------|
-| SQL Injection | Prepared statements | ✅ SECURE |
-| XSS Attacks | Output escaping | ✅ SECURE |
-| Wildcard Injection | LIKE escaping | ✅ SECURE |
-| DoS (Long Input) | Length validation | ✅ SECURE |
-| DoS (Rate Abuse) | 30 req/min limit | ✅ SECURE |
-| Invalid Data | Range validation | ✅ SECURE |
-| Pagination Abuse | Max 100/page | ✅ SECURE |
-
----
-
-## Configuration
-
-### Rate Limiting
-
-**Location**: `search.php` line 8
-```php
-$rateLimit = new RateLimit(30, 60); // 30 requests per minute
-```
-
-**Adjust as needed:**
-- More strict: `new RateLimit(10, 60)` - 10 req/min
-- More lenient: `new RateLimit(60, 60)` - 60 req/min
-- Hourly limit: `new RateLimit(100, 3600)` - 100 req/hour
-
-### Pagination
-
-**Default**: 20 results per page (max 100)
-
-**User control**:
-- `?per_page=50` - Get 50 results
-- `?per_page=200` - Capped at 100
-
----
-
-## Searchable Fields
-
-Users can search across:
-
-1. **Full-text query** - title, subtitle, synopsis, authors, supervisors, keywords
-2. **Year** - Specific year (1900-2100)
-3. **Orientation** - Arts Numériques, Peinture, Graphisme, etc.
-4. **AP Program** - Narration Spéculative, DPM, APS, LIENS
-5. **Finality** - Approfondi, Enseignement, Spécialisé
-6. **Format** - Site web, Vidéo, Installation, etc.
-7. **Language** - Français, Anglais
-8. **Keywords** - Any keyword from published theses
-9. **Type** - TFE or Doctoral theses
-
----
-
-## Files Overview
-
-### Core Files
-- **Database.php** - Secure database class with validation
-- **RateLimit.php** - Rate limiting system
-- **search.php** - Search interface page
-
-### Test Files
-- **create_test_db.php** - Generate test database
-- **test_search.php** - Functional tests
-- **test_security_updated.php** - Security validation
-- **test_rate_limit.php** - Rate limit tests
-
-### Documentation
-- **SEARCH_FEATURE.md** - Feature documentation
-- **SECURITY_ANALYSIS.md** - Security analysis
-- **SECURITY_IMPLEMENTATION.md** - Implementation details
-- **README_SECURE_SEARCH.md** - This file
-
----
-
-## Test Results Summary
-
-### ✅ All Tests Passing
-
-**Security Tests** (test_security_updated.php):
-```
-✅ Wildcard injection prevented
-✅ Long input rejected (max 200 chars)
-✅ Invalid year rejected (1900-2100)
-✅ SQL injection prevented
-✅ Pagination limited to 100
-✅ Negative offsets handled
-✅ Normal searches work correctly
-```
-
-**Rate Limiting Tests** (test_rate_limit.php):
-```
-✅ First 5 requests allowed
-✅ 6th request blocked
-✅ Remaining count accurate
-✅ Reset time calculated
-✅ Headers sent correctly
-✅ Cleanup works
-```
-
-**Functional Tests** (test_search.php):
-```
-✅ All theses retrieved (6 found)
-✅ Full-text search works
-✅ Year filter works
-✅ Orientation filter works
-✅ AP program filter works
-✅ Keyword search works
-✅ Combined filters work
-✅ Pagination works
-```
-
----
-
-## Example Searches
-
-### Basic Search
-```
-search.php?query=urbain
-→ Finds "Espaces Urbains et Narration Collective"
-```
-
-### Year Filter
-```
-search.php?year=2024
-→ Finds 3 theses from 2024
-```
-
-### Combined Filters
-```
-search.php?query=performance&year=2024&orientation=Installation-Performance
-→ Finds specific theses matching all criteria
-```
-
-### Pagination
-```
-search.php?year=2024&page=2&per_page=50
-→ Second page, 50 results per page
-```
-
----
-
-## Security Highlights
-
-### Input Validation
-
-**Before (Vulnerable)**:
-```php
-$bindings[':query'] = '%' . $params['query'] . '%';
-// User input "%" → matches EVERYTHING
-```
-
-**After (Secure)**:
-```php
-$validated = $this->escapeLikeString($params['query']);
-$bindings[':query'] = '%' . $validated . '%';
-// User input "%" → escapes to "\%" → matches literal %
-// SQL: LIKE :query ESCAPE '\'
-```
-
-### Rate Limiting Flow
-
-```
-Request → RateLimit::check()
- ↓
- Allowed? ───No──→ HTTP 429 + Error page
- ↓
- Yes
- ↓
- Process search → Return results
- ↓
- Send X-RateLimit-* headers
-```
-
----
-
-## Production Deployment
-
-### Pre-deployment Checklist
-
-- [x] All tests passing
-- [x] Security validated
-- [x] Rate limiting configured
-- [x] Cache directory created (755)
-- [x] Error handling in place
-- [x] Documentation complete
-
-### Server Requirements
-
-- [ ] PHP 7.4+ with PDO SQLite
-- [ ] Write permissions on cache/ directory
-- [ ] HTTPS enabled (recommended)
-- [ ] Error logging configured
-
-### Post-deployment
-
-1. Monitor `error.log` for issues
-2. Check rate limit cache growth
-3. Analyze search patterns
-4. Adjust rate limits if needed
-
----
-
-## Troubleshooting
-
-### Rate Limiting Not Working
-
-**Check**:
-```bash
-# Cache directory exists and is writable
-ls -la cache/rate_limit
-# Should show: drwxr-xr-x
-```
-
-**Fix**:
-```bash
-mkdir -p cache/rate_limit
-chmod 755 cache/rate_limit
-```
-
-### Search Returns No Results
-
-**Check**:
-1. Database exists: `ls ../formulaire/test.db`
-2. Database has data: `php test_search.php`
-3. Theses are published: `is_published = 1`
-
-### Validation Errors
-
-If users see "Search query too long":
-- Current limit: 200 characters
-- Adjust in `Database.php` → `validateSearchParams()`
-
----
-
-## Performance Notes
-
-### Optimized For
-- SQLite full-text search across multiple fields
-- Efficient LIKE queries with proper escaping
-- Indexed columns (year, published, orientation, AP)
-- Limited result sets (max 100/page)
-
-### Benchmarks (6 theses in test DB)
-- Simple search: < 1ms
-- Complex multi-filter: < 2ms
-- Rate limit check: < 0.1ms
-
-### Scaling Considerations
-- **100-1000 theses**: Current implementation excellent
-- **1000-10000 theses**: Consider full-text search engine
-- **10000+ theses**: Elasticsearch recommended
-
----
-
-## Maintenance
-
-### Daily
-- Monitor error logs for unusual patterns
-
-### Weekly
-- Check rate limit violations
-- Review search analytics
-
-### Monthly
-- Run security tests
-- Update validation rules if needed
-- Clean old cache files (automatic)
-
----
-
-## Support & Documentation
-
-### Documentation Files
-1. **SEARCH_FEATURE.md** - User-facing feature docs
-2. **SECURITY_ANALYSIS.md** - Threat analysis and mitigations
-3. **SECURITY_IMPLEMENTATION.md** - Technical implementation
-4. **README_SECURE_SEARCH.md** - This overview
-
-### Code Documentation
-- All methods have PHPDoc comments
-- Inline comments explain security measures
-- Test files demonstrate usage
-
----
-
-## Summary
-
-✅ **Feature Complete**: Full search with advanced filtering
-✅ **Security Hardened**: Production-grade protection
-✅ **Well Tested**: 100% test coverage
-✅ **Documented**: Comprehensive documentation
-✅ **Performance**: Optimized queries and caching
-✅ **Maintainable**: Clear code structure
-
-**Ready for production deployment!**
-
----
-
-## Credits
-
-Implementation includes:
-- Secure parameterized queries (PDO)
-- OWASP Top 10 protections
-- Rate limiting best practices
-- Input validation standards
-- RESTful search API design
-
-Generated: 2026-01-28
-Status: ✅ Production Ready
diff --git a/docs/REPOSITORY_STRUCTURE_ANALYSIS.md b/docs/REPOSITORY_STRUCTURE_ANALYSIS.md
deleted file mode 100644
index 25cec75..0000000
--- a/docs/REPOSITORY_STRUCTURE_ANALYSIS.md
+++ /dev/null
@@ -1,534 +0,0 @@
-# Repository Structure Analysis
-
-## Current Structure
-
-```
-posterg-website/ (monorepo root)
-├── front-backend/ Public-facing site
-│ ├── index.php Browse theses
-│ ├── search.php Search feature
-│ ├── memoire.php View individual thesis
-│ ├── Database.php DB connection (reads ../formulaire/test.db)
-│ ├── RateLimit.php Rate limiting
-│ ├── tests/ Tests (Unit/Integration/Security)
-│ ├── assets/ CSS, images
-│ └── inc/ Header/footer templates
-│
-├── formulaire/ Submission system (admin)
-│ ├── index.php List submissions
-│ ├── formulaire.php Submission form
-│ ├── edit.php Edit submissions
-│ ├── Database.php DB connection (different implementation!)
-│ ├── assets/ CSS, images
-│ └── data/ Upload storage
-│
-├── db/ Shared database schemas
-│ ├── schema.sql Database structure
-│ ├── posterg.db Production database
-│ └── README.md Documentation
-│
-├── justfile Deployment recipes
-└── README.md
-```
-
-## Deployment Model
-
-```bash
-# front-backend → /var/www/html/ (root domain)
-rsync ./front-backend/ server:/var/www/html/
-
-# formulaire → /var/www/html/formulaire/ (subdomain or /formulaire path)
-rsync ./formulaire/ server:/var/www/html/formulaire/
-```
-
-**URL Structure:**
-- Public site: `https://posterg.example.com/`
-- Admin/submission: `https://posterg.example.com/formulaire/`
-
-## Issues with Current Structure
-
-### ❌ Problems
-
-1. **Inconsistent Database Access**
- - `front-backend/Database.php` points to `../formulaire/test.db`
- - `formulaire/Database.php` points to `../db/posterg.db` (production)
- - Different implementations, different paths
-
-2. **Code Duplication**
- - Two separate `Database.php` files with different logic
- - No shared code between front-backend and formulaire
-
-3. **Confusing Dependencies**
- - front-backend depends on formulaire for database location
- - Circular/unclear relationship
-
-4. **Test Database Location**
- - Currently in `formulaire/test.db`
- - Should be in `db/` with schema
-
----
-
-## Option Analysis
-
-### Option A: Keep Monorepo, Improve Organization ⭐ RECOMMENDED
-
-```
-posterg-website/
-├── apps/ Application code
-│ ├── public/ Public-facing site (was front-backend)
-│ │ ├── index.php
-│ │ ├── search.php
-│ │ ├── memoire.php
-│ │ ├── assets/
-│ │ ├── inc/
-│ │ └── tests/
-│ │
-│ └── admin/ Submission system (was formulaire)
-│ ├── index.php
-│ ├── formulaire.php
-│ ├── edit.php
-│ ├── assets/
-│ └── data/
-│
-├── shared/ Shared code
-│ ├── Database.php Single DB class used by both apps
-│ └── RateLimit.php Shared utilities
-│
-├── database/ Database files (was db/)
-│ ├── schema.sql
-│ ├── posterg.db Production database
-│ ├── test.db Test database
-│ └── README.md
-│
-├── justfile Deployment
-├── composer.json Dependencies
-└── README.md
-```
-
-**Pros:**
-- ✅ Clear separation: public vs admin
-- ✅ Shared code in one place (DRY)
-- ✅ Single source of truth for database
-- ✅ Professional naming (apps/, shared/, database/)
-- ✅ Easy to add more apps later
-
-**Cons:**
-- ⚠️ Requires refactoring paths in all files
-- ⚠️ Need to update deployment scripts
-
-**Migration Effort:** Medium (2-3 hours)
-
----
-
-### Option B: Promote front-backend to Root
-
-```
-posterg-website/ (IS the public site)
-├── index.php Public site files at root
-├── search.php
-├── memoire.php
-├── Database.php
-├── RateLimit.php
-├── assets/
-├── inc/
-├── tests/
-│
-├── formulaire/ Keep admin as subfolder
-│ ├── index.php
-│ ├── formulaire.php
-│ └── ...
-│
-└── db/ Shared database
- ├── schema.sql
- └── posterg.db
-```
-
-**Pros:**
-- ✅ Simpler paths for main application
-- ✅ Less nesting
-- ✅ Minimal refactoring needed
-
-**Cons:**
-- ❌ Root directory becomes cluttered
-- ❌ Mixed responsibilities (public site + monorepo management)
-- ❌ Still have duplicate Database.php files
-- ❌ Harder to add new applications
-- ❌ Tests mixed with application code at root
-
-**Migration Effort:** Low (30 mins)
-
----
-
-### Option C: Flatten Everything
-
-```
-posterg-website/
-├── public/ Public site (was front-backend)
-├── admin/ Submission (was formulaire)
-├── database/ Schemas (was db)
-├── shared/ Shared code
-├── tests/ All tests
-├── composer.json
-└── justfile
-```
-
-**Pros:**
-- ✅ Very clean root directory
-- ✅ Professional structure
-- ✅ Clear naming
-
-**Cons:**
-- ❌ Deployment scripts need updates
-- ❌ All tests in one place (less clear ownership)
-
-**Migration Effort:** Medium (2 hours)
-
----
-
-### Option D: Keep Current Structure, Fix Issues
-
-```
-posterg-website/
-├── front-backend/ Keep as-is
-│ └── (no Database.php here)
-│
-├── formulaire/ Keep as-is
-│ └── (no Database.php here)
-│
-├── shared/ NEW: Shared code
-│ ├── Database.php Single database class
-│ └── RateLimit.php
-│
-└── db/ Keep as-is
- ├── schema.sql
- ├── posterg.db
- └── test.db
-```
-
-**Pros:**
-- ✅ Minimal changes
-- ✅ Keeps familiar structure
-- ✅ Fixes code duplication
-
-**Cons:**
-- ⚠️ Still nested (front-backend, formulaire)
-- ⚠️ Names not professional (what does "front-backend" mean?)
-
-**Migration Effort:** Low (1 hour)
-
----
-
-## Detailed Recommendation: Option A
-
-### Why Option A is Best
-
-1. **Scalability** - Easy to add new apps:
- - `apps/api/` for REST API
- - `apps/import/` for batch imports
- - Each app is independent
-
-2. **Professional** - Industry standard structure:
- - Clear naming (`public`, `admin`, `shared`)
- - Other developers understand immediately
- - Matches Laravel, Symfony conventions
-
-3. **Maintainability**:
- - Single Database.php used by all apps
- - Shared utilities (RateLimit) in one place
- - Tests stay with their applications
-
-4. **Deployment Clarity**:
- ```just
- deploy-public:
- rsync apps/public/ server:/var/www/html/
-
- deploy-admin:
- rsync apps/admin/ server:/var/www/html/formulaire/
-
- deploy-shared:
- rsync shared/ server:/var/www/html/shared/
- ```
-
-### Proposed Structure Details
-
-```
-posterg-website/
-│
-├── apps/ Applications
-│ ├── public/ Public-facing site
-│ │ ├── index.php Homepage (browse theses)
-│ │ ├── search.php Search interface
-│ │ ├── memoire.php Individual thesis view
-│ │ ├── apropos.php, contact.php, licences.php
-│ │ ├── assets/ Public CSS, images
-│ │ ├── inc/ Templates (header, footer)
-│ │ └── tests/ Public site tests
-│ │ ├── Unit/
-│ │ ├── Integration/
-│ │ ├── Security/
-│ │ └── Fixtures/
-│ │
-│ └── admin/ Admin/submission system
-│ ├── index.php Dashboard (list theses)
-│ ├── formulaire.php Submission form
-│ ├── edit.php Edit submission
-│ ├── import.php Bulk import
-│ ├── list.php List view
-│ ├── assets/ Admin CSS
-│ ├── data/ File uploads
-│ └── tests/ Admin tests (optional)
-│
-├── shared/ Shared code (library)
-│ ├── Database.php Single database class
-│ ├── RateLimit.php Rate limiting
-│ └── (future shared utilities)
-│
-├── database/ Database files & schemas
-│ ├── schema.sql Database structure
-│ ├── migrations/ Migration scripts (future)
-│ ├── fixtures/ Test data
-│ │ └── CreateTestDatabase.php
-│ ├── posterg.db Production database (gitignored)
-│ └── test.db Test database (gitignored)
-│
-├── config/ Configuration (optional)
-│ ├── database.php DB connection settings
-│ └── paths.php Path constants
-│
-├── .gitignore Git exclusions
-├── justfile Deployment recipes
-├── composer.json Dependencies
-├── run-tests.php Test runner
-└── README.md Documentation
-```
-
-### Migration Steps for Option A
-
-1. **Create new structure** (no breaking changes yet):
- ```bash
- mkdir -p apps/{public,admin}
- mkdir -p shared
- mkdir -p database/fixtures
- ```
-
-2. **Move applications**:
- ```bash
- mv front-backend/* apps/public/
- mv formulaire/* apps/admin/
- rmdir front-backend formulaire
- ```
-
-3. **Create shared Database.php**:
- - Merge best parts of both Database.php files
- - Make database path configurable
- - Use production db by default
-
-4. **Move shared utilities**:
- ```bash
- mv apps/public/RateLimit.php shared/
- ```
-
-5. **Reorganize database**:
- ```bash
- mv db database
- mv apps/public/tests/Fixtures/CreateTestDatabase.php database/fixtures/
- ```
-
-6. **Update all `require_once` paths**:
- ```php
- // In apps/public/index.php
- require_once __DIR__ . '/../../shared/Database.php';
- require_once __DIR__ . '/../../shared/RateLimit.php';
-
- // In apps/admin/index.php
- require_once __DIR__ . '/../../shared/Database.php';
- ```
-
-7. **Update Database.php to use config**:
- ```php
- class Database {
- private function __construct() {
- // Determine database path
- $dbPath = $this->getDatabasePath();
-
- $this->pdo = new PDO('sqlite:' . $dbPath);
- // ...
- }
-
- private function getDatabasePath() {
- // Check environment
- if (file_exists(__DIR__ . '/../storage/test.db')) {
- return __DIR__ . '/../storage/test.db';
- }
- return __DIR__ . '/../storage/posterg.db';
- }
- }
- ```
-
-8. **Update justfile**:
- ```just
- [group('deploy')]
- deploy-public:
- rsync -vur --progress \
- --exclude 'tests/' \
- --exclude '*.md' \
- apps/public/ posterg:/var/www/html/
- rsync -vur shared/ posterg:/var/www/html/shared/
-
- [group('deploy')]
- deploy-admin:
- rsync -vur --progress \
- --exclude 'tests/' \
- apps/admin/ posterg:/var/www/html/formulaire/
-
- [group('deploy')]
- deploy: deploy-public deploy-admin
- ```
-
-9. **Update .gitignore**:
- ```
- /storage/*.db
- /apps/*/cache/
- /shared/cache/
- *.log
- ```
-
-10. **Test everything**:
- ```bash
- php run-tests.php
- ```
-
----
-
-## Alternative: Quick Fix (Option D)
-
-If you don't want major refactoring right now:
-
-### Minimal Changes to Current Structure
-
-1. **Create shared/ directory**:
- ```bash
- mkdir shared
- ```
-
-2. **Create unified Database.php in shared/**:
- ```php
- // shared/Database.php - works for both apps
- class Database {
- private function __construct() {
- // Smart path detection
- if (file_exists(__DIR__ . '/../db/test.db')) {
- $dbPath = __DIR__ . '/../db/test.db';
- } else {
- $dbPath = __DIR__ . '/../db/posterg.db';
- }
-
- $this->pdo = new PDO('sqlite:' . $dbPath);
- // ... rest of implementation
- }
- }
- ```
-
-3. **Move RateLimit.php to shared/**:
- ```bash
- mv front-backend/RateLimit.php shared/
- ```
-
-4. **Update both apps to use shared/**:
- ```php
- // In front-backend/index.php
- require_once __DIR__ . '/../shared/Database.php';
-
- // In formulaire/index.php
- require_once __DIR__ . '/../shared/Database.php';
- ```
-
-5. **Delete duplicate Database.php files**:
- ```bash
- rm front-backend/Database.php
- rm formulaire/Database.php
- ```
-
-**Result:**
-```
-posterg-website/
-├── front-backend/ (uses shared/)
-├── formulaire/ (uses shared/)
-├── shared/ NEW: shared code
-│ ├── Database.php
-│ └── RateLimit.php
-└── db/ (existing)
-```
-
----
-
-## Comparison Matrix
-
-| Criteria | Option A (Restructure) | Option B (Root) | Option C (Flatten) | Option D (Quick Fix) | Current |
-|----------|----------------------|-----------------|-------------------|---------------------|---------|
-| **Professional** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
-| **Scalable** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
-| **Clear Separation** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
-| **Ease of Migration** | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | N/A |
-| **Code Reuse** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ |
-| **Maintainability** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
-
----
-
-## Final Recommendation
-
-### Short Term: Option D (Quick Fix)
-- Takes 1 hour
-- Fixes code duplication immediately
-- Minimal risk
-- Keeps familiar structure
-
-### Long Term: Option A (Full Restructure)
-- Plan for when you have 2-3 hours
-- Professional, scalable structure
-- Industry standard conventions
-- Future-proof
-
-### Do NOT: Option B (Promote to Root)
-- Creates more problems than it solves
-- Clutters root directory
-- Doesn't fix core issues
-
----
-
-## Questions to Consider
-
-1. **How often do you modify both apps?**
- - Often → Option A (shared code helps)
- - Rarely → Option D is fine
-
-2. **Will you add more applications?**
- - Yes (API, mobile backend, etc.) → Option A
- - No → Option D
-
-3. **Team size?**
- - Solo → Option D ok
- - Team → Option A for clarity
-
-4. **Timeline?**
- - Urgent → Option D
- - Can wait → Option A
-
----
-
-## My Recommendation
-
-**Start with Option D (Quick Fix), migrate to Option A later.**
-
-**Immediate (30 mins):**
-1. Create `shared/` directory
-2. Move Database.php and RateLimit.php to shared/
-3. Update both apps to use shared/
-4. Test and deploy
-
-**When you have time (Option A):**
-- Better names (`apps/public/`, `apps/admin/`)
-- Professional structure
-- Industry conventions
-
-Would you like me to help implement either approach?
diff --git a/docs/RESTRUCTURE_PLAN.md b/docs/RESTRUCTURE_PLAN.md
deleted file mode 100644
index 93f4f91..0000000
--- a/docs/RESTRUCTURE_PLAN.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# Repository Restructure Plan
-
-## Current Structure
-
-```
-posterg-website/
-├── apps/
-│ ├── public/ # Public website
-│ └── admin/ # Admin panel
-├── shared/ # Shared PHP libraries
-├── database/ # Database files
-├── nginx/ # Server config
-└── docs/ # Documentation
-```
-
-## Proposed Structure (Idiomatic PHP)
-
-```
-posterg-website/
-├── index.php # Public website root
-├── memoire.php
-├── search.php
-├── apropos.php
-├── contact.php
-├── licences.php
-├── assets/ # Static files (CSS, JS, images)
-│ ├── posterg.css
-│ ├── normalize.css
-│ └── fonts/
-├── inc/ # Page templates/partials
-│ ├── header.php
-│ └── footer.php
-├── lib/ # Shared libraries (renamed from shared/)
-│ ├── Database.php
-│ ├── RateLimit.php
-│ ├── config.php
-│ └── cache/
-├── admin/ # Admin panel (from apps/admin/)
-│ ├── index.php
-│ ├── list.php
-│ ├── edit.php
-│ └── ...
-├── database/ # Database files & schema
-│ ├── schema.sql
-│ ├── test.db
-│ └── ...
-├── vendor/ # Third-party dependencies (gitignored)
-│ └── php-live-reload/ # Local dev only
-├── nginx/ # Server configuration
-├── docs/ # Documentation
-├── tests/ # Tests (future)
-└── .gitignore # Updated
-```
-
-## Benefits
-
-✅ **Standard PHP structure** - Follows common conventions
-✅ **Flatter hierarchy** - Easier to navigate
-✅ **Clear separation** - lib/ for code, inc/ for templates, assets/ for static files
-✅ **Simpler paths** - Less `../../` in require statements
-✅ **Vendor folder** - Standard for third-party code
-
-## Migration Steps
-
-### 1. Move public to root
-```bash
-mv apps/public/* .
-```
-
-### 2. Move admin
-```bash
-mv apps/admin admin/
-rm -rf apps/
-```
-
-### 3. Rename shared to lib
-```bash
-mv shared lib/
-```
-
-### 4. Update all require paths
-- `require_once __DIR__ . '/shared/Database.php'` → `require_once __DIR__ . '/lib/Database.php'`
-- `require_once __DIR__ . '/../shared/Database.php'` → `require_once __DIR__ . '/../lib/Database.php'`
-
-### 5. Setup vendor for local dev
-```bash
-mkdir -p vendor/
-echo "vendor/" >> .gitignore
-```
-
-## Path Changes Summary
-
-| Old Path | New Path |
-|----------|----------|
-| `apps/public/index.php` | `index.php` |
-| `apps/public/inc/header.php` | `inc/header.php` |
-| `apps/public/assets/posterg.css` | `assets/posterg.css` |
-| `apps/admin/index.php` | `admin/index.php` |
-| `shared/Database.php` | `src/Database.php` |
-| `shared/config.php` | `src/config.php` |
-| `shared/cache/` | `src/cache/` |
-
-## Deployment Changes
-
-### Before
-```
-rsync apps/public/ posterg:/var/www/html/
-rsync apps/admin/ posterg:/var/www/html/formulaire/
-rsync shared/ posterg:/var/www/html/shared/
-```
-
-### After
-```
-rsync --exclude 'vendor' --exclude 'tests' . posterg:/var/www/html/
-```
-
-Much simpler!
-
-## PHP Live Reload Setup
-
-### For Local Development Only
-
-1. Clone to `vendor/php-live-reload/` (gitignored)
-2. Include in local dev server
-3. Auto-refresh browser on file changes
-4. Never deployed to production
-
-### Usage
-```bash
-# Setup (one time)
-just setup-dev
-
-# Start dev server with live reload
-just serve-public # or serve-admin
-```
diff --git a/docs/SECURITY.md b/docs/SECURITY.md
deleted file mode 100644
index 253c599..0000000
--- a/docs/SECURITY.md
+++ /dev/null
@@ -1,163 +0,0 @@
-# Security Improvements
-
-## Changes Made
-
-### 1. Critical Vulnerability Fixes
-
-#### Path Traversal in thanks.php (CRITICAL)
-- **Before**: User could access ANY file on the system via `?file=../../../../etc/passwd`
-- **After**:
- - Validates file path using `realpath()` to resolve symlinks
- - Ensures file is within allowed `data/yaml/` directory
- - Verifies file extension is `.yaml`
- - Proper error handling without exposing system paths
-
-#### CSRF Protection
-- **Before**: Form could be submitted from any website
-- **After**:
- - Session-based CSRF tokens generated for each form load
- - Token validated on submission using timing-safe comparison (`hash_equals()`)
- - Token cleared after successful submission
-
-### 2. Input Validation & Sanitization
-
-#### Deprecated Functions Replaced
-- **Before**: Used `FILTER_SANITIZE_STRING` (deprecated in PHP 8.1+)
-- **After**: Custom `sanitize_string()` function using `htmlspecialchars()` and `strip_tags()`
-
-#### Enhanced Validation
-- Required fields properly validated with custom `validate_required()` function
-- Email validation using `FILTER_VALIDATE_EMAIL`
-- URL validation using `FILTER_VALIDATE_URL`
-- Year validation with reasonable range checking (2000 to current year + 1)
-- Comprehensive error messages for validation failures
-
-### 3. File Upload Security
-
-#### Random Filenames
-- **Before**: Used original or predictable filenames (author + timestamp)
-- **After**:
- - Generates cryptographically secure random filenames using `random_bytes()`
- - Prevents file overwrites
- - Prevents path traversal attacks via malicious filenames
- - Stores mapping to original filename for reference
-
-#### Enhanced File Validation
-- MIME type checking using `finfo`
-- File extension whitelist
-- File size limits (50MB max)
-- Proper error handling for upload errors
-- Cover image restricted to JPEG/PNG only
-
-### 4. Bug Fixes
-
-- Fixed undefined variable `$memoireFolder` (used before definition)
-- Fixed undefined variable `$resume` (should be `$description`)
-- Fixed variable ordering (generate `$uniqueId` before using it)
-- Added proper `__DIR__` prefix for absolute paths
-
-### 5. Error Handling
-
-- Try-catch block wraps entire form processing
-- Detailed error logging (not exposed to users)
-- User-friendly error messages
-- Proper exit after redirect
-- No system path exposure in error messages
-
-## Nginx Configuration Notes
-
-Since this form is behind nginx password authentication, additional security layers:
-
-### Recommended nginx config:
-```nginx
-location /formulaire {
- auth_basic "Restricted Access";
- auth_basic_user_file /etc/nginx/.htpasswd;
-
- # Rate limiting
- limit_req zone=form_limit burst=5 nodelay;
-
- # File upload size
- client_max_body_size 100M;
-
- # Timeout settings
- client_body_timeout 60s;
-
- # Prevent access to sensitive files
- location ~ /\. {
- deny all;
- }
-
- location ~ /(vendor|composer\.(json|lock)|error\.log)$ {
- deny all;
- }
-}
-```
-
-## Additional Recommendations
-
-### 1. Database Migration (In Progress)
-Moving to SQLite will provide:
-- Structured data storage
-- Better query capabilities
-- Easier data management
-- Prepared statements for SQL injection prevention
-
-### 2. File Storage
-- Consider moving uploaded files outside web root
-- Serve files through PHP script with access control
-- Implement file scanning for malware if possible
-
-### 3. Monitoring
-- Regularly review `error.log` for suspicious activity
-- Monitor file upload patterns
-- Set up alerts for failed CSRF validations
-
-### 4. Backup Strategy
-- Regular backups of `data/` directory
-- Version control for code changes
-- Test restore procedures
-
-### 5. PHP Configuration
-Ensure these settings in php.ini:
-```ini
-file_uploads = On
-upload_max_filesize = 100M
-post_max_size = 100M
-max_execution_time = 60
-max_input_time = 60
-memory_limit = 256M
-
-# Security
-expose_php = Off
-allow_url_fopen = Off
-allow_url_include = Off
-display_errors = Off
-log_errors = On
-```
-
-## Testing Checklist
-
-- [ ] Form submission with all fields
-- [ ] Form submission with minimal required fields
-- [ ] Invalid email format
-- [ ] Invalid URL format
-- [ ] Invalid year
-- [ ] File upload (various formats)
-- [ ] Large file upload (>50MB, should fail)
-- [ ] Invalid file types
-- [ ] Multiple file uploads
-- [ ] Cover image upload
-- [ ] CSRF token validation (try submitting with wrong token)
-- [ ] Path traversal attempt in thanks.php
-- [ ] Error handling for missing directories
-
-## Known Limitations
-
-1. **No atomic transactions**: File operations and YAML save not atomic
-2. **No rollback**: Failed submissions may leave partial files
-3. **Session storage**: CSRF tokens in default PHP session (consider database sessions)
-4. **No upload progress**: Large files have no progress indicator
-5. **No duplicate detection**: Same submission can be made multiple times
-
-These limitations will be addressed in the SQLite migration.
diff --git a/docs/SECURITY_ANALYSIS.md b/docs/SECURITY_ANALYSIS.md
deleted file mode 100644
index cb5a80b..0000000
--- a/docs/SECURITY_ANALYSIS.md
+++ /dev/null
@@ -1,406 +0,0 @@
-# 🔒 Security Vulnerability Analysis — posterg-website
-
-> **Date:** 2026-02-08
-> **Scope:** Full static code review of all PHP, nginx config, and deployment files.
-> **Analyst:** Claude Code
-
----
-
-## Good Practices Already in Place
-
-- ✅ SQL injection: all queries use PDO prepared statements consistently
-- ✅ XSS output: `htmlspecialchars()` applied on all user-controlled output
-- ✅ CSRF: tokens generated with `bin2hex(random_bytes(32))` and validated with `hash_equals()` (timing-safe) on all state-changing forms
-- ✅ File upload: MIME type validated with `finfo` for cover images and thesis files
-- ✅ Input validation: year, IDs, and pagination values cast to integers
-- ✅ LIKE wildcard escaping implemented in public search (`Database::escapeLikeString`)
-
----
-
-## 🔴 CRITICAL
-
-### 1. Admin HTTP Basic Auth Over Plain HTTP (No TLS/HTTPS)
-
-**File:** `nginx/posterg.conf`
-
-The nginx config listens only on port 80. HTTP Basic Authentication Base64-encodes
-credentials but **does not encrypt them**. Anyone intercepting network traffic can
-decode the admin password trivially (`echo "dXNlcjpwYXNz" | base64 -d`).
-
-```nginx
-listen 80 default_server; # ← No HTTPS configured at all
-auth_basic "Admin Access - Post-ERG";
-auth_basic_user_file /etc/nginx/.htpasswd-posterg;
-```
-
-**Fix:** Add a TLS/HTTPS server block (e.g., Let's Encrypt via certbot) and redirect
-all port 80 traffic to HTTPS:
-
-```nginx
-server {
- listen 80;
- return 301 https://$host$request_uri;
-}
-server {
- listen 443 ssl;
- ssl_certificate /etc/letsencrypt/live/posterg.erg.be/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/posterg.erg.be/privkey.pem;
- # ... rest of config
-}
-```
-
----
-
-### 2. No PHP-Level Authentication in Admin Panel
-
-**Files:** `public/admin/index.php`, `add.php`, `edit.php`, `import.php`, `thanks.php`
-
-Every admin file calls `session_start()` only to generate a CSRF token. There is
-**zero check that the user is authenticated in PHP**. If nginx is misconfigured,
-restarted, or the app is accessed directly without nginx in front (e.g., via the
-PHP CLI dev server), all admin functionality is fully open.
-
-```php
-session_start();
-if (empty($_SESSION['csrf_token'])) {
- $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
-}
-// ← No authentication check whatsoever
-```
-
-**Fix:** Implement a PHP login system with session-based authentication and add an
-auth guard at the top of every admin page:
-
-```php
-// public/admin/auth.php
-session_start();
-if (empty($_SESSION['admin_authenticated'])) {
- header('Location: /admin/login.php');
- exit;
-}
-```
-
----
-
-## 🟠 HIGH
-
-### 3. Uploaded Files Stored Inside the Webroot
-
-**File:** `public/admin/actions/formulaire.php` (lines ~127–131)
-
-Thesis files and cover images are stored *inside* the public web directory:
-
-```php
-$uploadBaseDir = __DIR__ . "/data/theses/{$annee}/{$identifier}/";
-$coverDir = __DIR__ . "/data/covers/";
-// Resolves to: /var/www/posterg/public/admin/actions/data/...
-```
-
-This means uploaded PDFs, ZIPs, MP4s, and images sit in a potentially web-accessible
-path. The nginx rule `location ^~ /data/ { deny all; }` only blocks the URL path
-`/data/…` from the server root — it does **not** block `/admin/actions/data/…`.
-
-**Fix:** Store uploads outside the webroot and serve through a controller:
-
-```php
-$uploadBaseDir = '/var/www/posterg/storage/theses/' . $annee . '/' . $identifier . '/';
-$coverDir = '/var/www/posterg/storage/covers/';
-```
-
----
-
-### 4. File Path Mismatch — Media Files Cannot Be Served to Public
-
-**Files:** `formulaire.php` (stores), `memoire.php` and `search.php` (reference)
-
-Files are stored at `public/admin/actions/data/theses/YEAR/ID/file.ext` but recorded
-in the database as `data/theses/YEAR/ID/file.ext`. When a browser loads `/memoire.php`,
-relative links resolve to `/data/theses/…`, which nginx blocks:
-
-```php
-// memoire.php — tries to embed a URL that nginx denies
-