Skip to content

Navigation Menu

Sign in
Sign up

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

FlowGT — Open Reference

The engineering a recruitment service should be willing to show you. Matching logic, consent evidence, encryption, deletion — from the systems behind flowgt.co.nz, published so you can verify instead of trust.

Code: AGPL-3.0 or Commercial Docs: CC BY-NC-ND 4.0 Law: NZ Privacy Act 2020 Email: UEMA 2007


💡 Why this exists — the founding intent

A recruitment service holds the most personal documents people have: their CVs, their job searches, their outcomes. Every agency says it handles these carefully. Saying it is cheap.

Trust cannot be asserted. It can only be verified. So the parts of our engineering that decide whether we deserve trust — how consent is recorded, how unsubscribe works, how CVs are encrypted, how matching ranks a person's opportunities, when data is deleted — are published here, with the New Zealand law they answer to quoted clause by clause.

  • 🧑‍💼 If you are an employer — read how roles are matched and ranked before they ever reach a candidate.
  • 🧑‍🎓 If you are a candidate — read exactly what happens to your data, and check our claims against the statutes yourself.

🧭 Design philosophy

Five principles, enforced as acceptance criteria on every file:

Principle What it means here
🔒 Structure over promise A rule that matters becomes a schema constraint or a test — never only a sentence. Consent is a verbatim record, not a boolean.
🪪 Evidence, not assertion UEMA s 9(3) puts the burden of proof on the sender — so every consent row can answer "what exactly did they agree to?" years later.
🔇 Silence must be distinguishable from failure "We checked and there was nothing" ≠ "we failed" ≠ "we never ran". Three different rows, never one.
🧹 Clean No personal data, no credentials, no internal traces. Verified before every publication, not assumed.
⚖️ Neutral Legal claims quote the statute, with a source link, a verification date, and a credibility grade. Open questions stay marked open.

🗺️ Map of the repository

mindmap
 root((FlowGT<br/>Open Reference))
 🎯 matching/
 roles.js — the ranking logic
 ARCHITECTURE.md — design record
 digest-runs.sql — the honest ledger
 🛡️ privacy/
 unsubscribe.js — one click, no login
 no-member-data.py — the data gate
 schema/
 consent-subscriptions.sql
 consent-v2-migration.sql
 cv-encryption.sql
 retention.sql — the 24-month promise
 📚 compliance/
 UEMA 2007 — email law
 Privacy Act 2020
 Fair Trading Act
 candidate fees · e-signature
 immigration advice · platform terms
 ⚖️ LICENSING.md — the Qt model
Loading

📬 How an email leaves this system

Every arrow below exists because a law or a failure mode demands it.

flowchart TD
 A[👤 Member turns email ON<br/>in their own portal] -->|verbatim sentence +<br/>time + source recorded| B[(🪪 Consent evidence<br/>job_subscriptions)]
 B --> C{⏰ Weekday?<br/>consent says weekdays only}
 C -->|weekend| Z1[🚫 Nothing sends]
 C -->|weekday| D[🎯 Match & rank<br/>relevance ORDERS, never drops]
 D --> E{Fresh roles?}
 E -->|none| Q[😴 outcome: quiet<br/>recorded — not a failure]
 E -->|yes| F[📧 Send digest<br/>≤25 per bucket]
 F --> G[(📒 Ledger<br/>digest_runs + snapshot)]
 F --> H[🔗 One-click unsubscribe<br/>in every footer]
 H -->|no login required| I[(🔕 Sticky opt-out<br/>re-consent needed to return)]
 G --> J[🖥️ Member portal shows<br/>send-time snapshot<br/>email & page never disagree]
 classDef consent fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#1b5e20
 classDef ledger fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#0d47a1
 classDef stop fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#b71c1c
 classDef action fill:#fff8e1,stroke:#f9a825,stroke-width:2px,color:#795500
 class A,B consent
 class G,I,J ledger
 class Z1,H stop
 class C,D,E,F,Q action
Loading

🗄️ Data model — the tables published here

erDiagram
 ACCOUNTS ||--o| JOB_SUBSCRIPTIONS : "one consent record"
 ACCOUNTS ||--o{ DIGEST_RUNS : "one per send attempt"
 DIGEST_RUNS ||--o{ DIGEST_RUN_JOBS : "send-time snapshot"
 ACCOUNTS ||--o{ CV_DOCUMENTS : "encrypted, versioned"
 CV_DOCUMENTS ||--o{ CV_REVIEWS : "audited AI ledger"
 ACCOUNTS ||--o| RETENTION_NOTICES : "30-day warning"
 RETENTION_LOG }o..|| ACCOUNTS : "hash only, after deletion"
 JOB_SUBSCRIPTIONS {
 text consent_text "the exact sentence agreed to"
 int consent_at
 text unsub_token "one click, no login"
 int unsubbed_at "sticky"
 }
 DIGEST_RUNS {
 text outcome "running | sent | quiet | failed"
 text trigger_kind "scheduled never impersonated"
 int n_shown "NULL on failure, never 0"
 }
 CV_DOCUMENTS {
 text ciphertext "AES-256-GCM"
 text consent_text "recorded at upload"
 }
 RETENTION_NOTICES {
 int notified_at
 int delete_after "notice + 30 days"
 }
 RETENTION_LOG {
 text email_hash "sha256 — no identity kept"
 int deleted_at
 }
Loading

♻️ The 24-month promise — data deletion with notice

The privacy page promises it; this machinery delivers it (privacy/schema/retention.sql):

flowchart LR
 A[🕐 Any sign-in<br/>or activity] -->|resets| B[⏳ 24-month clock]
 B -->|23 months silent| C[📨 Notice email:<br/>30 days' warning]
 C -->|one sign-in| B
 C -->|30 more days<br/>of silence| D[🗑️ Deletion<br/>cascades everywhere]
 D --> E[(🧾 Ledger keeps a<br/>one-way hash only)]
 classDef ok fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#1b5e20
 classDef warn fill:#fff8e1,stroke:#f9a825,stroke-width:2px,color:#795500
 classDef del fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#b71c1c
 class A,B ok
 class C warn
 class D,E del
Loading
  • Any activity resets the clock — one sign-in is enough.
  • 📨 Nothing is deleted without warning — a notice goes out 30 days ahead.
  • 🧾 After deletion, only a hash remains: keeping the identity of the person you deleted, to prove you deleted them, is a contradiction.

📚 What is in here

Folder For whom Contents
🎯 matching/ Employers & candidates The scoring logic, the design record, and the delivery ledger — including why relevance orders and never drops
🛡️ privacy/ Candidates & anyone we email Consent evidence, unsubscribe, CV encryption, the data gate, retention
📚 privacy/compliance/ Anyone checking our claims The NZ legal reference library — verbatim statutes, source links, verification dates, credibility grades

⚖️ The law behind the design

File Governs One-sentence verdict
uema-2007-email.md 📧 Commercial email & SMS No B2B exemption; burden of proof is on the sender
privacy-act-2020.md 🪪 CVs, contact data Collect only what's relevant; destroy on schedule; IPP 3A governs indirect collection
candidate-fees.md 💰 Revenue model Charging candidates anything is illegal; money comes from employers only
fair-trading-act.md 📢 Website claims Only verifiable claims may be published
immigration-advice.md 🛂 Conversations No immigration advice, ever — it requires a licence we do not hold
e-signature.md ✍️ Contracts Electronic signatures fully valid (CCLA 2017 ss 226–228)
platform-terms.md 🔌 Data sources Only channels whose purpose is to be read

Nothing here is legal advice — each file carries its own disclaimer.

📜 Licence — the Qt model

Dual-licensed. Code: your choice of AGPL-3.0-only (free — but your derivative work, including SaaS, must be open-sourced too) or a paid FlowGT commercial licence for closed-source use. Documents: CC BY-NC-ND 4.0.

Reading, studying and citing are always free. Unauthorised commercial use will be pursued under New Zealand law. Details: LICENSING.md · NOTICE.md · commercial enquiries hello@flowgt.co.nz

🚫 Scope

  • This is not the full product — the website, business logic and operational tooling are private.
  • This is not a community project — no feature requests, no pull requests. It is published as verifiable reference, and that is its whole job.

About

The engineering a recruitment service should be willing to show you — matching, consent evidence, CV encryption, 24-month deletion, and the NZ law behind it. Verify, don't trust. Dual-licensed (Qt model).

Topics

Resources

Security policy

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /