--- name: printable-test-qr-codes description: Create repo-tracked printable QR code sheets for manual mobile QA against deployed app routes, then verify and deliver them back to the user. version: 1.0.0 tags: [qr-code, qa, mobile, print, deployment] --- # Printable Test QR Codes Use this when the user wants a QR code they can print or save to their phone for manually testing a deployed web app flow. ## Workflow 1. **Identify the canonical live URL** - Prefer a public HTTPS route on `*.apps.poofc.com`. - If the QR needs a specific seeded record/table/bill, trace the app's seed/reset/data creation flow first. - Verify the target route exists publicly before generating the final QR. 2. **Add/ensure deterministic test data** - If the app has a seed script, add a stable slug/record there. - If the app has a dev reset endpoint, update it too so the QR can be restored after testing. - Keep the QR target stable, e.g. `/t/paradiso/test-table`, not a generated database ID. 3. **Generate repo-tracked print assets** - Store assets under `docs/test-qr/`. - Generate at least: - a printable full-page PNG sheet - a PDF version for printing - an SVG QR for lossless repo use - optionally a bare QR PNG - Use high error correction (`ERROR_CORRECT_H`) and a generous border for scan reliability. - Include visible text on the sheet: app/test name, target context, URL, and a short QA note. 4. **Python generation pattern** ```python from pathlib import Path import qrcode from qrcode.image.svg import SvgPathImage from PIL import Image, ImageDraw, ImageFont repo = Path('/path/to/repo') out = repo / 'docs' / 'test-qr' out.mkdir(parents=True, exist_ok=True) url = 'https://APP.apps.poofc.com/path/to/test' base_name = 'app-test-name' qr = qrcode.QRCode( version=None, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=18, border=4, ) qr.add_data(url) qr.make(fit=True) qr_img = qr.make_image(fill_color='#111111', back_color='white').convert('RGB') qr_img.save(out / f'{base_name}-qr.png') svg_img = qrcode.make(url, image_factory=SvgPathImage, error_correction=qrcode.constants.ERROR_CORRECT_H) svg_img.save(out / f'{base_name}.svg') # 8.5x11 at 300dpi W, H = 2550, 3300 sheet = Image.new('RGB', (W, H), 'white') d = ImageDraw.Draw(sheet) def font(size, bold=False): candidates = [ '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf' if bold else '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', '/usr/share/fonts/truetype/liberation2/LiberationSans-Bold.ttf' if bold else '/usr/share/fonts/truetype/liberation2/LiberationSans-Regular.ttf', ] for p in candidates: try: return ImageFont.truetype(p, size) except Exception: pass return ImageFont.load_default() def center_text(text, y, size=64, bold=False, fill='#111111'): f = font(size, bold) bbox = d.textbbox((0, 0), text, font=f) d.text(((W - (bbox[2] - bbox[0])) // 2, y), text, font=f, fill=fill) center_text('Test QR', 260, 108, True) center_text('Context / Table / Flow', 405, 76) center_text('Scan to open the live test flow', 520, 58, fill='#444444') qr_large = qr_img.resize((1500, 1500), Image.Resampling.NEAREST) sheet.paste(qr_large, ((W - 1500) // 2, 760)) center_text(url, 2380, 48) center_text('Manual QA note: reset data before/after testing if needed.', 2480, 40, fill='#555555') center_text('Print at 100% scale for best scan reliability.', 2550, 40, fill='#555555') sheet.save(out / f'{base_name}.png', dpi=(300, 300)) sheet.save(out / f'{base_name}.pdf', 'PDF', resolution=300.0) ``` 5. **Document in README** - Add the live QR target URL. - List the checked-in asset paths. - Mention the reset/seed behavior that restores the test record. 6. **Verify** - Run the app build if code changed. - Seed/reset the data in the deployed environment. - Restart the relevant PM2 process if API code changed. - Verify: - target HTML route returns 200 - backing API/data endpoint returns the expected seeded record - generated PNG/PDF/SVG files exist and are valid (`file`, `du -h`) - use `vision_analyze` on the PNG sheet to confirm the visible URL/text is correct 7. **Commit, push, and deliver** - Commit and push repo changes. - Send the PNG and PDF back to the user as native media with `MEDIA:/absolute/path`. ## Pitfalls - Do not point a QR at a random generated ID if the DB can be reseeded. Use a stable slug/path. - If payment/testing mutates the record, make sure seed and `/api/dev/reset` restore the QR target. - `npm install` can rewrite `package-lock.json` peer metadata. If dependency files were not intentionally changed, inspect and revert unrelated lockfile churn before committing. - Some auto-lint hooks from file patching may invoke `tsc` without the project config and show irrelevant TypeScript errors. Still run the actual project build command (`npm run build`) for verification. - Browser automation may fail in sandboxed VPS environments; API + file + vision verification is often enough for QR asset work.