readme add
This commit is contained in:
@@ -1 +1,632 @@
|
|||||||
test 2d
|
💍 Wedding Site
|
||||||
|
|
||||||
|
A personal wedding website with guest authentication, RSVP forms, event information, and an administration panel.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
📖 About the Project
|
||||||
|
|
||||||
|
Wedding Site is a web application designed for a wedding event.
|
||||||
|
|
||||||
|
The website allows guests to:
|
||||||
|
|
||||||
|
* receive a personalized invitation;
|
||||||
|
* authenticate using a unique access code;
|
||||||
|
* view the wedding schedule;
|
||||||
|
* get information about transportation and travel;
|
||||||
|
* browse photos;
|
||||||
|
* fill out a guest questionnaire;
|
||||||
|
* specify food and drink preferences;
|
||||||
|
* leave a personal message or request.
|
||||||
|
|
||||||
|
The organizers have access to administrative features for managing guests.
|
||||||
|
|
||||||
|
The project is a full-stack application with a Python backend and a native HTML/CSS/JavaScript frontend.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
✨ Features
|
||||||
|
|
||||||
|
👰 For Guests
|
||||||
|
|
||||||
|
* 🔐 Authentication using a unique 6-digit code
|
||||||
|
* 🎫 Personalized access to the invitation
|
||||||
|
* 📅 Wedding day schedule
|
||||||
|
* 🚗 Transportation and travel information
|
||||||
|
* 📸 Photo gallery
|
||||||
|
* 📝 Guest questionnaire
|
||||||
|
* 🍽️ Food preferences
|
||||||
|
* 🥂 Drink preferences
|
||||||
|
* 💬 Ability to leave a message or request
|
||||||
|
* 🚪 Secure logout
|
||||||
|
|
||||||
|
👨💼 For Administrators
|
||||||
|
|
||||||
|
* 👥 View the guest list
|
||||||
|
* ➕ Create new guests
|
||||||
|
* ✏️ Edit guest information
|
||||||
|
* 🔑 Manage guest access codes
|
||||||
|
* 📊 View guest activation status
|
||||||
|
* 🕐 Track the last login time
|
||||||
|
* 🛡️ Role-based administrative access
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🏗️ Architecture
|
||||||
|
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ Guest │
|
||||||
|
│ Browser / Mobile │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│
|
||||||
|
HTTPS / HTTP
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ Caddy │
|
||||||
|
│ Reverse Proxy / TLS │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ FastAPI │
|
||||||
|
│ Backend │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│
|
||||||
|
┌──────────────────┼──────────────────┐
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||||
|
│ JWT │ │ Pydantic │ │ SQLAlchemy │
|
||||||
|
│ Auth │ │ Validation │ │ ORM │
|
||||||
|
└─────────────┘ └─────────────┘ └──────┬──────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────┐
|
||||||
|
│ SQLite │
|
||||||
|
│ guests.db │
|
||||||
|
└─────────────┘
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🧰 Technologies
|
||||||
|
|
||||||
|
Backend
|
||||||
|
|
||||||
|
Technology Purpose
|
||||||
|
Python 3.13 Core programming language
|
||||||
|
FastAPI REST API
|
||||||
|
Uvicorn ASGI server
|
||||||
|
Pydantic Data validation
|
||||||
|
SQLAlchemy 2 ORM
|
||||||
|
SQLite Database
|
||||||
|
aiosqlite Async SQLite driver
|
||||||
|
Alembic Database migrations
|
||||||
|
PyJWT JWT authentication
|
||||||
|
|
||||||
|
Frontend
|
||||||
|
|
||||||
|
Technology Purpose
|
||||||
|
HTML5 Markup
|
||||||
|
CSS3 Styling
|
||||||
|
JavaScript Client-side logic
|
||||||
|
Swiper.js Sliders and gallery
|
||||||
|
|
||||||
|
Infrastructure
|
||||||
|
|
||||||
|
Technology Purpose
|
||||||
|
Docker Containerization
|
||||||
|
Docker Compose Container orchestration
|
||||||
|
Caddy Reverse proxy and HTTPS
|
||||||
|
Ansible Deployment automation
|
||||||
|
Gitea Actions CI/CD
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
📁 Project Structure
|
||||||
|
|
||||||
|
.
|
||||||
|
├── .gitea/
|
||||||
|
│ └── workflows/
|
||||||
|
│ └── ci.yml
|
||||||
|
│
|
||||||
|
├── ansible/
|
||||||
|
│ ├── deploy.yml
|
||||||
|
│ ├── inventory.ini
|
||||||
|
│ └── secrets.yml
|
||||||
|
│
|
||||||
|
├── docker/
|
||||||
|
│ ├── caddy/
|
||||||
|
│ ├── gitea_runner_image/
|
||||||
|
│ ├── gitea_runners/
|
||||||
|
│ ├── docker-compose.yaml
|
||||||
|
│ ├── dockerfile.project
|
||||||
|
│ └── start.sh
|
||||||
|
│
|
||||||
|
├── server/
|
||||||
|
│ ├── backend/
|
||||||
|
│ │ ├── auth/
|
||||||
|
│ │ │ └── JWT.py
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── database/
|
||||||
|
│ │ │ ├── DB/
|
||||||
|
│ │ │ ├── alembic/
|
||||||
|
│ │ │ └── db.py
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── endpoints/
|
||||||
|
│ │ │ └── endpoints.py
|
||||||
|
│ │ │
|
||||||
|
│ │ └── schema/
|
||||||
|
│ │ └── pydantic.py
|
||||||
|
│ │
|
||||||
|
│ └── frontend/
|
||||||
|
│ ├── auth/
|
||||||
|
│ │ ├── fonts/
|
||||||
|
│ │ ├── image/
|
||||||
|
│ │ ├── login.css
|
||||||
|
│ │ ├── login.html
|
||||||
|
│ │ └── login.js
|
||||||
|
│ │
|
||||||
|
│ └── main/
|
||||||
|
│ ├── fonts/
|
||||||
|
│ ├── images/
|
||||||
|
│ ├── api.js
|
||||||
|
│ ├── index.html
|
||||||
|
│ ├── main.js
|
||||||
|
│ ├── reset.css
|
||||||
|
│ └── style.css
|
||||||
|
│
|
||||||
|
├── .gitignore
|
||||||
|
├── env_example
|
||||||
|
├── makefile
|
||||||
|
├── requirements.txt
|
||||||
|
└── run.py
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🔐 Authentication
|
||||||
|
|
||||||
|
Authentication is based on a personal access code assigned to each guest.
|
||||||
|
|
||||||
|
Guest
|
||||||
|
│
|
||||||
|
│ 6-digit code
|
||||||
|
▼
|
||||||
|
POST /api/auth
|
||||||
|
│
|
||||||
|
├── Validate user
|
||||||
|
├── Verify access code
|
||||||
|
├── Update last_login
|
||||||
|
└── Generate JWT
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
HTTP-only Cookie
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Authenticated
|
||||||
|
|
||||||
|
The JWT is stored in a cookie and used for subsequent API requests.
|
||||||
|
|
||||||
|
The authentication cookie uses the following security attributes:
|
||||||
|
|
||||||
|
HttpOnly
|
||||||
|
Secure
|
||||||
|
SameSite=Strict
|
||||||
|
|
||||||
|
The JWT secret key and token configuration are provided through environment variables.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🔌 API
|
||||||
|
|
||||||
|
Main API endpoints:
|
||||||
|
|
||||||
|
Method Endpoint Description Auth
|
||||||
|
POST /api/auth Guest authentication ❌
|
||||||
|
GET /api/verify Verify authentication ✅
|
||||||
|
POST /api/logout Logout ✅
|
||||||
|
POST /api/update Update guest information ✅
|
||||||
|
POST /api/create Create a guest 👑
|
||||||
|
GET /api/list Get the guest list 👑
|
||||||
|
|
||||||
|
Where:
|
||||||
|
|
||||||
|
* ✅ — authenticated user;
|
||||||
|
* 👑 — administrator only.
|
||||||
|
|
||||||
|
Swagger
|
||||||
|
|
||||||
|
Interactive API documentation is available at:
|
||||||
|
|
||||||
|
/api/docs
|
||||||
|
|
||||||
|
ReDoc
|
||||||
|
|
||||||
|
/api/redoc
|
||||||
|
|
||||||
|
OpenAPI
|
||||||
|
|
||||||
|
/api/openapi.json
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🗄️ Database
|
||||||
|
|
||||||
|
The project uses SQLite as its database.
|
||||||
|
|
||||||
|
Main entity:
|
||||||
|
|
||||||
|
users
|
||||||
|
|
||||||
|
The table contains:
|
||||||
|
|
||||||
|
* user ID;
|
||||||
|
* access code;
|
||||||
|
* first name;
|
||||||
|
* middle name;
|
||||||
|
* last name;
|
||||||
|
* personal message or request;
|
||||||
|
* food preferences;
|
||||||
|
* drink preferences;
|
||||||
|
* activation status;
|
||||||
|
* creation timestamp;
|
||||||
|
* update timestamp;
|
||||||
|
* last login timestamp;
|
||||||
|
* administrator privileges.
|
||||||
|
|
||||||
|
The database layer uses an asynchronous stack:
|
||||||
|
|
||||||
|
FastAPI
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
SQLAlchemy 2
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
aiosqlite
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
SQLite
|
||||||
|
|
||||||
|
Database schema changes are managed using Alembic.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🚀 Local Development
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
|
||||||
|
Before running the project, install:
|
||||||
|
|
||||||
|
* Python 3.13+
|
||||||
|
* pip
|
||||||
|
* SQLite
|
||||||
|
|
||||||
|
For Docker-based deployment:
|
||||||
|
|
||||||
|
* Docker
|
||||||
|
* Docker Compose
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
1. Clone the Repository
|
||||||
|
|
||||||
|
git clone https://git.homyk.space/MH.Dmitrii/wedding-site.git
|
||||||
|
cd wedding-site
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
2. Create a Virtual Environment
|
||||||
|
|
||||||
|
Linux / macOS
|
||||||
|
|
||||||
|
python3.13 -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
|
||||||
|
Windows
|
||||||
|
|
||||||
|
py -3.13 -m venv .venv
|
||||||
|
.venv\Scripts\activate
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
3. Install Dependencies
|
||||||
|
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
4. Environment Variables
|
||||||
|
|
||||||
|
Create a .env file in the project root.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
DIR=/path/to/project
|
||||||
|
PORT=8000
|
||||||
|
SECRET_KEY=change-me
|
||||||
|
ALGORITHM=HS256
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS=3600
|
||||||
|
|
||||||
|
You can use env_example as a reference when configuring the environment.
|
||||||
|
|
||||||
|
⚠️ Never commit a real SECRET_KEY to Git.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
5. Run the Application
|
||||||
|
|
||||||
|
python run.py
|
||||||
|
|
||||||
|
Or using Make:
|
||||||
|
|
||||||
|
make run
|
||||||
|
|
||||||
|
Debug mode:
|
||||||
|
|
||||||
|
make run_debug
|
||||||
|
|
||||||
|
After starting, the application will be available at:
|
||||||
|
|
||||||
|
http://localhost:8000
|
||||||
|
|
||||||
|
Swagger:
|
||||||
|
|
||||||
|
http://localhost:8000/api/docs
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🐳 Docker
|
||||||
|
|
||||||
|
Docker Compose is used for production-like deployments.
|
||||||
|
|
||||||
|
Start the application:
|
||||||
|
|
||||||
|
docker compose -f docker/docker-compose.yaml up -d
|
||||||
|
|
||||||
|
Check running containers:
|
||||||
|
|
||||||
|
docker compose -f docker/docker-compose.yaml ps
|
||||||
|
|
||||||
|
View logs:
|
||||||
|
|
||||||
|
docker compose -f docker/docker-compose.yaml logs -f
|
||||||
|
|
||||||
|
Stop the application:
|
||||||
|
|
||||||
|
docker compose -f docker/docker-compose.yaml down
|
||||||
|
|
||||||
|
The SQLite database is persisted using a Docker volume, so recreating the container should not remove the database data.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🧬 Database Migrations
|
||||||
|
|
||||||
|
The project uses Alembic for database migrations.
|
||||||
|
|
||||||
|
Check the current migration:
|
||||||
|
|
||||||
|
make migrate_current
|
||||||
|
|
||||||
|
Apply all migrations:
|
||||||
|
|
||||||
|
make migrate_head
|
||||||
|
|
||||||
|
Rollback the latest migration:
|
||||||
|
|
||||||
|
make migrate_down
|
||||||
|
|
||||||
|
View migration history:
|
||||||
|
|
||||||
|
make migrate_history
|
||||||
|
|
||||||
|
View migration heads:
|
||||||
|
|
||||||
|
make migrate_heads
|
||||||
|
|
||||||
|
Create a new migration:
|
||||||
|
|
||||||
|
make migrate
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
⚙️ Makefile
|
||||||
|
|
||||||
|
The project provides a Makefile with shortcuts for common development and database operations.
|
||||||
|
|
||||||
|
Main commands:
|
||||||
|
|
||||||
|
make run
|
||||||
|
make run_debug
|
||||||
|
make migrate_current
|
||||||
|
make migrate_head
|
||||||
|
make migrate_down
|
||||||
|
make migrate_history
|
||||||
|
make migrate_heads
|
||||||
|
make migrate
|
||||||
|
|
||||||
|
To see all available commands:
|
||||||
|
|
||||||
|
make help
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🔄 CI/CD
|
||||||
|
|
||||||
|
The project uses Gitea Actions for automation.
|
||||||
|
|
||||||
|
The general workflow:
|
||||||
|
|
||||||
|
git push
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌───────────────┐
|
||||||
|
│ Gitea Actions │
|
||||||
|
└───────┬───────┘
|
||||||
|
│
|
||||||
|
┌─────────┴─────────┐
|
||||||
|
▼ ▼
|
||||||
|
Build Docker Deployment
|
||||||
|
│ │
|
||||||
|
▼ ▼
|
||||||
|
Docker Image Ansible
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Docker Compose
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Production
|
||||||
|
|
||||||
|
The workflow builds the Docker image and performs deployment to the target environment.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🌐 Production
|
||||||
|
|
||||||
|
The production infrastructure consists of:
|
||||||
|
|
||||||
|
Internet
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Caddy
|
||||||
|
│
|
||||||
|
│ HTTPS
|
||||||
|
▼
|
||||||
|
FastAPI
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
SQLite
|
||||||
|
|
||||||
|
Caddy acts as a reverse proxy and handles external HTTP/HTTPS traffic.
|
||||||
|
|
||||||
|
Ansible is used to automate deployment and server configuration.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
📱 Frontend
|
||||||
|
|
||||||
|
The frontend does not use React, Vue, Angular, or other SPA frameworks.
|
||||||
|
|
||||||
|
The main stack is:
|
||||||
|
|
||||||
|
HTML
|
||||||
|
CSS
|
||||||
|
JavaScript
|
||||||
|
|
||||||
|
This keeps the client-side application lightweight and easy to deploy.
|
||||||
|
|
||||||
|
Main pages:
|
||||||
|
|
||||||
|
/auth/login.html
|
||||||
|
/main/index.html
|
||||||
|
|
||||||
|
JavaScript is responsible for:
|
||||||
|
|
||||||
|
* authentication;
|
||||||
|
* API communication;
|
||||||
|
* mobile navigation;
|
||||||
|
* sliders;
|
||||||
|
* interactive elements;
|
||||||
|
* countdown timer;
|
||||||
|
* guest questionnaire submission.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🧪 Development
|
||||||
|
|
||||||
|
Recommended development workflow:
|
||||||
|
|
||||||
|
Feature branch
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Development
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Commit
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Push
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Gitea Actions
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Build
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Deploy
|
||||||
|
|
||||||
|
Before pushing changes, it is recommended to run:
|
||||||
|
|
||||||
|
python -m compileall .
|
||||||
|
|
||||||
|
and verify that the application starts correctly in the local environment.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🔒 Security
|
||||||
|
|
||||||
|
For production deployment, make sure to:
|
||||||
|
|
||||||
|
* use a strong, randomly generated SECRET_KEY;
|
||||||
|
* use HTTPS;
|
||||||
|
* never commit .env files to Git;
|
||||||
|
* never store production secrets in plain text;
|
||||||
|
* restrict access to the SQLite database;
|
||||||
|
* regularly back up the database;
|
||||||
|
* disable debug mode in production.
|
||||||
|
|
||||||
|
⚠️ Deployment configuration and secrets should be reviewed carefully before making the repository public.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
🗺️ Roadmap
|
||||||
|
|
||||||
|
Possible future improvements:
|
||||||
|
|
||||||
|
* Add comprehensive automated tests
|
||||||
|
* Add API test coverage
|
||||||
|
* Add SQLite backup and restore
|
||||||
|
* Add a dedicated admin frontend
|
||||||
|
* Add guest response statistics
|
||||||
|
* Add guest list export to Excel/CSV
|
||||||
|
* Add rate limiting to /api/auth
|
||||||
|
* Add CSRF protection for cookie-based authentication
|
||||||
|
* Add centralized logging
|
||||||
|
* Add a dedicated healthcheck endpoint
|
||||||
|
* Add application monitoring
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
📊 Project
|
||||||
|
|
||||||
|
Main languages used in the project:
|
||||||
|
|
||||||
|
HTML ████████████████████ 40.5%
|
||||||
|
CSS ███████████████ 29.5%
|
||||||
|
Python ██████████ 20.9%
|
||||||
|
JavaScript ████ 7.6%
|
||||||
|
Makefile ▏ 0.7%
|
||||||
|
|
||||||
|
The statistics are based on the current state of the repository.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
📄 License
|
||||||
|
|
||||||
|
No explicit license is currently specified in the repository.
|
||||||
|
|
||||||
|
If the project is intended to be distributed as open source, it is recommended to add a:
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
file and specify the chosen license in this section.
|
||||||
|
|
||||||
|
⸻
|
||||||
|
|
||||||
|
👨💻 Author
|
||||||
|
|
||||||
|
MH.Dmitrii
|
||||||
|
|
||||||
|
Repository:
|
||||||
|
|
||||||
|
https://git.homyk.space/MH.Dmitrii/wedding-site
|
||||||
|
|||||||
Reference in New Issue
Block a user