Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Activity_Simulator

Automated Python bot that simulates day-to-day shop activity for PrimeAutocare, so the live demo shows fresh, realistic activity instead of static seed data. Two independent GitHub Actions cron-scheduled workflows provide continuous, zero-touch data generation with no human intervention.

Architecture

flowchart LR
    C1["activity.yml cron<br/>(2x/day)"] --> P1["activity.py"]
    P1 -- "login + REST calls" --> API["PrimeAutocare API"]
    API --> DB[("PostgreSQL")]

    C2["worklogs.yml cron<br/>(nightly)"] --> P2["worklogs.py"]
    P2 -- "psycopg2 (direct)" --> DB
Loading

Technical Highlights

  • Workflow automation — two independent jobs orchestrated by GitHub Actions on cron schedules, each performing a bounded, idempotent unit of work per trigger
  • REST API client integrationactivity.py authenticates against a JWT/cookie-based session (via a persistent requests.Session) and drives the live backend exactly like a real user, exercising the same validation, business-rule constraints, and HTTP status handling a browser client would
  • Direct database accessworklogs.py connects to PostgreSQL via psycopg2, bypassing the API where the API itself can't express the need (backdating historical timestamps)
  • Synthetic/test data generation — randomized, bounded data generation algorithms (jittered timestamps, probability-gated actions) that produce realistic-looking records without runaway, unbounded growth
  • Idempotency — both scripts check existing state before writing, so re-running a workflow (manually or via retry) never produces duplicate data
  • Least-privilege security model — a dedicated, scoped bot service account (role-based) rather than reusing an administrator credential

It's two independent workflows, split by how they reach the data:

Script How it writes Why
scripts/activity.py Through the real API, logged in as a bot employee Jobs, invoices, and payments all go through the backend's own validation, status-transition rules, and constraints — exactly like a real user's actions would
scripts/worklogs.py Directly into Postgres The attendance endpoints always stamp datetime.now() server-side, so there's no way to give an employee a realistic historical shift (a specific clock-in/out time) through the API

activity.py — Simulate Shop Activity

Runs a bounded, randomized slice of shop activity each time it's triggered: progresses a few pending jobs to in-progress and a few in-progress jobs to completed, occasionally creates a new job (mostly against an existing customer/vehicle, sometimes a brand-new one), raises invoices for newly completed jobs, and records payments (full or partial) against outstanding invoices.

Runs twice a day via .github/workflows/activity.yml.

Required secrets:

  • API_BASE_URL — the deployed backend URL
  • BOT_USERNAME / BOT_PASSWORD — login for a dedicated bot employee account

One-time setup: the bot account

The bot needs an employee row with role A or S (job/invoice/payment writes require one of those roles). Easiest way: log into the app as an existing admin, go to Employees, and add one — name it something obviously synthetic like "Bot User", give it role S, and use its username/password as the two secrets above. No manual SQL required.

worklogs.py — Simulate Worklogs

Once per simulated day, generates one attendance row per employee directly in the attendance table: a clock-in and clock-out time jittered around shop hours (some early, some late, some short shifts, some long/overtime), with a small chance any given employee is simply absent that day (no row at all). Skips a day entirely if attendance already exists for it, so re-runs or manual triggers don't double-insert.

Runs nightly via .github/workflows/worklogs.yml, after the simulated shop day ends. Trigger manually with a specific date to backfill history:

gh workflow run worklogs.yml -f date=2026-07-15

Required secret:

  • DATABASE_URL — same Postgres connection string used by PrimeAutocare's own keepalive workflow

Tuning

Shop hours, jitter ranges, absence rate, and the closed weekday are constants at the top of worklogs.py; per-run volume caps and probabilities for activity.py are constants at the top of that file. Adjust either directly rather than adding configuration plumbing — this is a two-script repo, not a framework.

Local development

pip install -r requirements.txt
DATABASE_URL=... python scripts/worklogs.py
API_BASE_URL=... BOT_USERNAME=... BOT_PASSWORD=... python scripts/activity.py

Team

About

Automated bot that simulates day-to-day shop activity via the live API

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages