Web platform for sending, storing, and managing anonymous comments. It is built with native PHP in a modular structure, uses PostgreSQL for persistence and audit logging, and uses Redis to enforce submission rate limiting while preserving anonymity.
The project allows any unauthenticated user to submit feedback anonymously. The administrator (Owner) accesses a secure dashboard to review messages, change statuses, and manage records. The system does not store IP addresses in plain text and uses Redis for temporary submission rate limiting.
Note
🚧 Work in Progress
This project is currently in an active development and refactoring phase. The base architecture, PostgreSQL/Redis schemas, and flowcharts are already structured, but the complete source code continues to receive regular updates.
- PHP 8.4.1+
- PostgreSQL 15+
- Redis 6+
- Composer
- PHPUnit
- FastRoute
- PHP-DI
- Symfony HttpFoundation
- Feedback submissions are anonymous and do not require authentication.
- The administrator can access the protected interface to read and manage messages.
- Feedback status changes are audited in
feedback_recordsusing a PostgreSQL trigger. - Redis applies a rate limit to submissions (maximum 10 messages per 10 minutes per anonymous identifier).
Make sure the following system and PHP dependencies are installed:
- PHP
>= 8.4.1with extensions:pdo_pgsql,redis,mbstring,json,xml - Composer
>= 2.0 - PostgreSQL
>= 15 - Redis Server
>= 6.0 php-cli,php-xml,php-mbstring,php-pgsql,php-curlunzip,curl,postgresql-contrib,redis-server
This project uses PHP dependencies installed with Composer to support the architecture and testing:
FastRoute— HTTP request routing and route handling.PHP-DI— dependency injection to decouple controllers, repositories, and services.Symfony HttpFoundation— abstraction layer for HTTP requests and responses.PHPUnit— testing framework to validate backend behavior.
- PHP: server-side language that processes incoming requests, validates forms, executes business logic, and generates HTTP responses.
- PostgreSQL: stores the system's persistent information: users, feedbacks, states, and change audit logs. The
feedback_state_change()trigger maintains the state change history infeedback_records. - Redis: in-memory service that controls anonymous submission frequency with rate limiting, without persisting IP addresses or sensitive sender data.
docs/– project documentation.scripts/– scripts to manage PostgreSQL, Redis, and setup.src/– TBDschema.sql– table definitions, relationships, and audit trigger.seed.sql– initial database data..env.example– environment variable template.composer.json- configuration file where project dependencies and versions are defined.composer.lock- handles "freezing" and registering the exact versions of dependencies.
Copy .env.example to .env and complete the values for your environment:
DATABASE_NAME=
DATABASE_USER=
DATABASE_PASSWORD=
DATABASE_PORT=
REDIS_PORT=- Install Composer:
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer- Install Docker and Docker Compose.
Note
🚧 Docker installation
Docker installation may vary depending on the operating system; I recommend researching the steps for your OS.
- Build and start the containers:
docker-compose up --build -d- Access the application at
http://localhost:8000and the PostgreSQL database atdocker compose exec db psql -U feedback_user -d feedback.
- Install system dependencies (the
scripts/setup.shscript installs common Debian/Ubuntu packages):
bash scripts/setup.sh- Install PHP dependencies with Composer:
composer installAccess PostgreSQL as the superuser:
sudo -u postgres psqlCreate the application database and user:
CREATE DATABASE <database-name>;
CREATE USER <database_user> WITH PASSWORD 'secure_password_here';Connect to the newly created database:
\c <database_name>Grant the required schema permissions and default privileges:
-- Grant schema creation and usage (Required for PostgreSQL 15+)
GRANT ALL ON SCHEMA public TO <database_user>;
GRANT CONNECT ON DATABASE <database_name> TO <database_user>;
GRANT USAGE, CREATE ON SCHEMA public TO <database_user>;
-- Grant DML privileges on existing objects
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO <database_user>;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO <database_user>;
-- Set default privileges for future tables and sequences
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO <database_user>;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO <database_user>;(Optional alternative: ALTER SCHEMA public OWNER TO <database_user>;)
Execute the database migrations and seed files using TCP host binding (-h 127.0.0.1) to enforce password authentication:
psql -h 127.0.0.1 -U <database_user> -d <database_name> -f schema.sql
psql -h 127.0.0.1 -U <database_user> -d <database_name> -f seed.sqlThis project uses Redis to control the rate of message submissions. The scripts/redis.sh script can start, stop, and check the service.
Start Redis:
bash scripts/redis.sh --startCheck status:
bash scripts/redis.sh --statusEnter the Redis CLI:
bash scripts/redis.sh --cli- Start PostgreSQL:
bash scripts/database.sh --start- Start Redis:
bash scripts/redis.sh --start- Run your PHP server or the local development server according to the application configuration.
- Make sure
.envcontains the correct values before starting the application. - The audit trigger
feedback_state_change()records state changes infeedback_records. - The system is designed to preserve anonymity and not persist identity-linked data associated with messages.