A Rust-based application that automatically distributes household chores among residents every two weeks. The system uses a PostgreSQL database to track people and assignment history, ensuring fair rotation and preventing repetitive assignments.
- Automated Scheduling: Runs daily via GitHub Actions but only generates assignments every 14 days
- Fair Rotation: Tracks assignment history to ensure people don't get the same tasks repeatedly
- Group-Based Constraints: Enforces rules based on group membership (Group A vs Group B)
- Discord Integration: Automatically posts new assignments to Discord when generated
- Database-Backed: Uses Neon PostgreSQL for persistent state management
- Stateless Execution: Perfect for CI/CD environments
The application follows a stateless architecture where all state is stored in a PostgreSQL database. For a detailed explanation of the system architecture, including diagrams and data flow, see docs/architecture.md.
- Daily Check: GitHub Actions runs the application daily at 9 AM UTC
- 14-Day Rule: The app checks if 14 days have passed since the last assignment
- Assignment Generation: If eligible, generates new fair work distributions
- Discord Notification: Posts results to Discord (only when new assignments are made)
- Rust (latest stable version)
- PostgreSQL database (we recommend Neon)
- Diesel CLI:
cargo install diesel_cli --no-default-features --features postgres
git clone https://github.com/onelrian/VividShift.git
cd VividShiftCreate a .env file in the project root:
DATABASE_URL=postgresql://user:password@host/dbname?sslmode=require
RUST_LOG=infodiesel migration runThis will:
- Create the
peopleandassignmentstables - Seed initial data from legacy files (if present)
cargo runStores resident information and group assignments.
| Column | Type | Description |
|---|---|---|
| id | SERIAL | Primary key |
| name | TEXT | Person's name |
| group_type | TEXT | 'A' or 'B' |
| active | BOOLEAN | Active status |
Tracks assignment history for rotation logic.
| Column | Type | Description |
|---|---|---|
| id | SERIAL | Primary key |
| person_id | INTEGER | Foreign key to people |
| task_name | TEXT | Assigned task |
| assigned_at | TIMESTAMP | Assignment date |
Configure these in your GitHub repository settings:
DATABASE_URL: Your Neon PostgreSQL connection stringDISCORD_WEBHOOK: Discord webhook URL for notifications
The workflow runs daily but only sends notifications when new assignments are generated:
schedule:
- cron: '0 9 * * *' # Daily at 9 AM UTCThe Rust application enforces the 14-day interval internally.
Edit the work_assignments HashMap in src/main.rs:
let work_assignments: HashMap<String, usize> = [
("Parlor".to_string(), 5),
("Frontyard".to_string(), 3),
("Backyard".to_string(), 1),
("Tank".to_string(), 2),
("Toilet B".to_string(), 4),
("Toilet A".to_string(), 2),
("Bin".to_string(), 1),
]
.into_iter()
.collect();Insert or update records in the people table:
-- Add a new person to Group A
INSERT INTO people (name, group_type, active) VALUES ('John', 'A', true);
-- Deactivate a person
UPDATE people SET active = false WHERE name = 'John';Modify the eligibility logic in src/group.rs:
// Example: Group B restriction for Toilet A
let is_from_b_in_toilet_a = *area == "Toilet A" && names_b_set.contains(person);Run the test suite:
cargo testTests cover:
- Assignment distribution logic
- Constraint enforcement
- Edge cases (insufficient people, etc.)
vividshift/
├── src/
│ ├── main.rs # Entry point, schedule checking
│ ├── db.rs # Database operations
│ ├── group.rs # Assignment algorithm
│ ├── models.rs # Diesel ORM models
│ ├── schema.rs # Database schema
│ └── output.rs # Formatting utilities
├── migrations/ # Diesel migrations
├── docs/
│ └── architecture.md # Detailed architecture docs
└── .github/workflows/
└── worker.yml # GitHub Actions workflow
# Build
cargo build
# Run with database check
cargo run
# Run tests
cargo test
# Format code
cargo fmtThis error occurs when the constraints are too restrictive. Possible solutions:
- Check that you have enough people for all tasks
- Review the assignment history (people might be blocked from all available tasks)
- Consider adjusting the
HISTORY_LENGTHinsrc/db.rs
Ensure:
- Your
DATABASE_URLis correct in.env - The database is accessible from your network
- Migrations have been run successfully
Check:
- The
SHOULD_NOTIFYenvironment variable is set totrue(only happens when assignments are generated) - Your
DISCORD_WEBHOOKsecret is configured correctly - The workflow has the necessary permissions
MIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.