Wednesday, 5 November 2025
Ceo
# Auto CEO
Automated procurement of groceries from https://www.tesco.ie
> **TL;DR**
> Auto CEO is a cloud-hosted service + mobile/desktop client that keeps a dynamic grocery “playbook”, watches Tesco.ie prices/stock, updates the customer’s on-site basket, and performs scheduled or rules-based check-out with secure credential escrow.
> Below you will find: functional spec, architecture, data-model, workflow diagrams, code snippets (Python + Playwright, FastAPI, React), DevOps pipeline, and a 90-day delivery roadmap.
---
## 1. Caveats & Compliance
1. Tesco’s public API was discontinued; automation therefore requires either
a) a **commercial agreement** with Tesco for B2B/partner API access, **or**
b) browser automation that respects Tesco’s ToS, rate limits, CAPTCHA, and GDPR.
2. Auto CEO **must store credentials off-site** (e.g., HashiCorp Vault) and never harvest data for resale.
3. If you pursue option (b), add an “I am using automation” disclosure in your ToS and provide a kill-switch in case Tesco objects.
---
## 2. Functional Requirements
| Epic | User Story | Acceptance Criteria |
| ---- | ---------- | ------------------- |
| Core Basket | “As a user, I upload or build a grocery template.” | Items stored, variant SKUs resolved. |
| Price & Stock Monitor | “Alert me if any item exceeds my max price or is out of stock.” | Push & email within 60 s of change. |
| Auto-Cart | “Every Mon 07:00, fill my Tesco basket with the playbook items, respecting quantity rules.” | Verified basket ID returned. |
| Rules-Based Checkout | “If total < €150 and delivery slot 18:00-20:00 is free, checkout.” | Confirmation email + Tesco order ID stored. |
| Budget Guard | “Never exceed monthly spend of €600.” | Hard block with explanation. |
| Multi-Profile | Household, Office, AirBnB apartment profiles. | Separated lists, budgets, credentials. |
| Audit | Download monthly CSV of orders & savings. | File generates under 5 s. |
---
## 3. Target Users & Personas
1. Busy households
2. Office managers (bulk, repeat orders)
3. Short-stay property hosts
4. Elderly relatives (caretaker manages remotely)
---
## 4. High-Level Architecture
```
┌──────────────────────────────────┐
│ React / React-Native Frontend │
└──────────────┬───────────────────┘
│REST/GraphQL
┌──────────────▼───────────────────┐
│ FastAPI (Python 3.12) │
│ ─────────────┬─────────────── │
│ Auth & ACL │Scheduler (Celery)│
│ BasketSvc │PriceWatcher │
│ BudgetGuard │TescoBot Worker │
└───────┬───────┴─────────┬────────┘
│gRPC (internal) │Async MQ (Rabbit)
┌───────▼────────┐ ┌────▼────────┐
│PostgreSQL 15 │ │Redis (cache)│
└────────────────┘ └─────────────┘
│ │
│ Headless Chromium │
▼ │
┌─────────────────────────────┐│
│ Playwright-based TescoBot │◄─ Tesco.ie
└─────────────────────────────┘
```
Containerised with Docker, orchestrated by Kubernetes (k3s for dev, EKS in prod).
---
## 5. Data Model (simplified ERD)
```
User ────< Profile ────< PlaybookItem
│ │
│ ┌───────┴───────┐
│ │ TescoSKU │
│ └───────────────┘
│
OrderHistory BudgetRule Alert
```
---
## 6. Interaction Flow
1. User logs into Auto CEO → OAuth (Auth0) → obtains Dashboard JWT.
2. Builds “Weekly Office” playbook (milk, coffee, fruit).
3. Cron (Celery beat) ticks Monday 06:55 UTC → TescoBot spins.
4. TescoBot uses Playwright: login → clear basket → add SKUs → attempt slot → place order.
5. On success: Tesco order ID stored; confirmation emailed; web-hook triggers Slack for office manager.
6. If rule violation (budget, price spike), task aborts and raises Alert.
---
## 7. Key Modules & Snippets
### 7.1 TescoBot (Python, Playwright)
```python
# tesco_bot/basket.py
from playwright.async_api import async_playwright
import asyncio, os
TESCO_EMAIL = os.getenv("TESCO_EMAIL")
TESCO_PASS = os.getenv("TESCO_PASS")
async def add_items(items: list[tuple[str,int]]):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()
# 1. Login
await page.goto("https://www.tesco.ie/groceries/en-IE/login")
await page.fill('input[type="email"]', TESCO_EMAIL)
await page.fill('input[type="password"]', TESCO_PASS)
await page.click('button[type="submit"]')
await page.wait_for_selector('text="My Account"', timeout=15000)
# 2. Clear basket
await page.goto("https://www.tesco.ie/groceries/en-IE/app/basket")
while await page.query_selector('button:has-text("Remove")'):
await page.click('button:has-text("Remove")')
await page.wait_for_timeout(300)
# 3. Add items
for sku, qty in items:
await page.goto(f"https://www.tesco.ie/groceries/en-IE/products/{sku}")
for _ in range(qty):
await page.click('button:has-text("Add")')
await page.wait_for_timeout(250)
# 4. Book slot & checkout (simplified)
await page.goto("https://www.tesco.ie/groceries/en-IE/slots")
await page.click('button:has-text("18:00 - 20:00")')
await page.click('button:has-text("Checkout")')
await page.wait_for_selector('text="Thank you for your order"', timeout=15000)
order_num = await page.text_content('h2.order-number')
await browser.close()
return order_num
if __name__ == "__main__":
items = [("3000005114579", 2), # Tesco Fresh Milk 2 L
("300178028", 1)] # Nescafé Gold Blend 200 g
order = asyncio.run(add_items(items))
print("Order placed:", order)
```
Note: selectors may change; add proper error-handling, retry, CAPTCHA solve (e.g., 2Captcha).
### 7.2 Backend API (FastAPI excerpt)
```python
# api/routers/playbook.py
from fastapi import APIRouter, Depends, HTTPException
from schemas import PlaybookCreate, PlaybookOut
from services import playbook_svc
router = APIRouter(prefix="/playbooks")
@router.post("/", response_model=PlaybookOut)
async def create_playbook(payload: PlaybookCreate, user=Depends(get_current_user)):
pb = await playbook_svc.create(user.id, payload)
if not pb:
raise HTTPException(400, "Could not create")
return pb
```
### 7.3 Scheduler (Celery beat)
```python
# celery beat schedule
{
"auto_cart_weekly": {
"task": "tasks.run_playbook",
"schedule": crontab(minute=0, hour=7, day_of_week=1),
"args": (playbook_id,)
}
}
```
---
## 8. Security Considerations
1. Credentials stored encrypted with AES-256 in Vault; decrypted only inside Kubernetes Job.
2. TescoBot container has **no outbound internet** except tesco.ie and captcha solver.
3. Column-level encryption for budget & address data (GDPR).
4. 2FA: user supplies TOTP for Auto CEO, but Tesco only supports SMS/email. Build a prompt to the user if Tesco challenges.
---
## 9. CI/CD & DevOps
1. GitHub Actions → lint, test, Docker build → push to ECR.
2. Terraform controls VPC, RDS Postgres, EKS.
3. Sentry for backend, BrowserStack for Playwright visual regression.
4. ArgoCD pulls manifests; blue/green deployments.
---
## 10. 90-Day Roadmap
| Phase | Weeks | Deliverables |
| ----- | ----- | ------------ |
| Discovery | 1-2 | Stakeholder interviews, ToS review, tech spike on Playwright. |
| MVP Sprint 1 | 3-6 | Auth, Playbook CRUD, manual “Run Now” TescoBot. |
| MVP Sprint 2 | 7-10 | Scheduler, budget rules, price watcher. |
| Beta | 11-12 | Mobile (React-Native), webhook integrations, penetration test. |
| Launch | 13 | Prod cut-over, onboarding docs, marketing site. |
---
## 11. Future Enhancements
1. Multi-retailer plugins (Aldi, Dunnes) via adapter interface.
2. ML-driven demand forecast (seasonality).
3. Shared community playbooks (“Irish Keto”, “Toddler Essentials”).
4. Carbon footprint tracker & eco-friendly substitutions.
---
### Final Notes
• Always pursue an official API or partnership first; stealth scraping can break anytime.
• Limit 5–8 concurrent bot sessions to stay under the radar.
• Keep human-in-the-loop: send pre-checkout push notification “Proceed?” to avoid surprises.
With this blueprint you can kick-off development immediately, and within three months have a compliant, secure Auto CEO that quietly fills your Tesco trolley every week.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment