Appearance
Privacy and security
🔴 Read before scoping. These are design inputs, not a compliance appendix — three of them change the data model, so resolving them after a design round means redoing it.
The source analysis is a growth and revenue document. It treats privacy as monetisation Layer 2 — a paid tier of "protected sections, photo access request, temporary links, profile expiry". That framing is commercially reasonable and, as the primary safety posture, it is the single most dangerous idea in the plan.
If the free tier's default disclosure is unsafe, then safety is not a feature to sell — it is a defect to fix. A model where the paid tier is safe and the free tier is not converts a duty of care into a price list, and it inverts under scrutiny: the users least able to pay are the ones most exposed.
⚠ These risks compound with growth rather than trading off against it. Every mechanism in the growth model — frictionless public links, no-login viewing, "create yours" on every page, matchmaker bulk creation — increases exposure in direct proportion to how well it works. That is unusual and it is why this page sits ahead of the commercial ones.
0. The standing rule: consumer data is PII and is NEVER indexed
Owner decision, and it applies to every consumer surface, not only this feature:
Consumer-side data is PII. It is not indexed, and there is no SEO consideration on the consumer side. A marriage biodata is the correct first example of the rule.
This is a stronger constraint than a <meta name="robots"> tag, and it has a consequence that is easy to miss and expensive to get wrong.
⚠ It is a CACHING rule before it is an indexing rule
The vendor Setu Card is served Cache-Control: s-maxage=604800 — seven days in a shared edge cache — because it is public, identical for every visitor, and wants reach.
A consumer biodata is none of those things. It is personal, access-controlled, and different per recipient. Inheriting the card's caching would hand one person's biodata to the next visitor.
The codebase already contains the correct precedent, and states the reasoning verbatim. apps/web/src/app/routes/order-status.tsx is the platform's existing PII page:
"What must never happen is the page being CACHED or CRAWLED: an edge cache would serve one buyer's order to whoever asked next, and an index entry would publish it. Hence
no-storeandnoindex, inheaders()rather than only inmeta(), because a crawler that never runs JS still reads the header.⚠ AND NOTE WHAT THE REST OF THIS APP DOES:
/:slugis serveds-maxage=604800, seven days. If this route inherited that, one buyer's confirmation would be handed to the next visitor for a week. The headers below are the only thing standing between those two facts."
A marriage biodata must inherit
order-status.tsx's posture, notsetu-card.tsx's.no-storeandnoindex, set inheaders()and not only inmeta().
What follows from the rule
| Consequence | Class |
|---|---|
| No edge caching — which also means ADR-0027's purge-on-write design, and the outbox nothing drains, are not needed here. A simplification, not a cost. | ✅ Removes work |
| Every view hits the origin. At 500,000+ views this is a real infrastructure line item — the price of the posture, not a bug. | 🔵 Scalability |
| No sitemap, no structured data, no OG image on a crawlable surface. Rich WhatsApp previews still work — they are fetched by the messenger, not indexed by a search engine — but the preview content is itself a disclosure decision. | ⬜ Design input |
| No public discovery, search or browse of consumer profiles. This removes screens a designer would otherwise assume. | ⬜ Design input |
| SEO belongs only to marketing surfaces — a public biodata generator or landing page may be indexed. A person's biodata never is. | 🟨 Keep the two apart |
⚠ The last row is the one to watch. The growth plan proposes a free biodata generator as an SEO channel. That is legitimate for the tool page. The moment an indexed page contains a real person's details, the rule is broken.
1. This is sensitive personal data about people who did not sign up
A marriage biodata carries, conventionally: full name, exact date of birth, photographs, height, education, employer, income, home city or address, family members' names and occupations, and frequently religion, caste, sub-caste and gotra.
Three facts make this materially heavier than a vendor's Setu Card:
- The subject is often not the account holder. A parent publishes a daughter's photographs. Consent is a real object with a real lifecycle, not a signup checkbox.
- The audience is strangers. The whole point is reaching families you do not know.
- The population skews young and female, and the data set is close to ideal for stalking, harassment, impersonation and fraud.
What must be decided, not assumed:
- Does the subject have to confirm before publication, on their own device?
- Can the subject unpublish a page the creator owns? (My position: yes, unconditionally.)
- What is the default disclosure for a new profile — open, or closed?
2. Caste and community data
Indian matrimonial convention includes caste, sub-caste and gotra, and a product that omits the field will be seen as unusable by a large part of the market. This is a genuine product tension, not a compliance formality, and it needs an explicit owner decision rather than a default:
- It is special-category / sensitive data under most privacy regimes and is treated as such in the DPDP Act's spirit.
- Storing it is defensible; making it a filterable, indexable, or algorithmically-matched attribute is a different and much larger decision with reputational and regulatory exposure.
- A middle position exists: store it as free-text within the private tier, never as a structured facet, never in the open tier, never indexed, never a search dimension.
⚠ Do not let this be settled implicitly by a form field. If a designer adds a caste dropdown because every competitor has one, the decision has been made without being taken.
3. DPDP Act 2023 obligations scale with success
At the plan's own target of 100,000 users holding sensitive personal data, this stops being a light-touch obligation:
| Obligation | What it means here |
|---|---|
| Purpose limitation + notice | Consent must be specific. "Improving our services" does not cover showing a person's photographs to strangers. |
| Erasure | A subject can demand deletion. That has to reach the page, R2 media, analytics and any AI-extraction pipeline. ⚠ Two measured complications. (1) User lifecycle covers accounts, not third-party subjects, and here the subject may not be the account holder. (2) The owner has decided a slug is soft-deleted and realigned on return — which retains an identifier, and cannot be honoured for an erasure request. The resolution (tombstone the slug with no personal data attached) is in My QR Setu. ⚠ Today manage-account performs a HARD delete via auth.admin.deleteUser (index.ts:113), cascading public.users away entirely, so neither path is implemented as decided. |
| Breach notification | Timelines are tight and the data is sensitive. |
| Children's data | Age verification matters when the population is young; the Act treats under-18 data with extra restriction. |
| Significant Data Fiduciary | Volume plus sensitivity can trigger heavier duties, including a Data Protection Officer and audits. Not a Year-1 certainty, but not ignorable at breakout scale either. |
⚠ The "Create from PDF" AI extraction feature (source analysis §24) is a data-processing decision. Uploading a biodata PDF and running it through an extraction model means sensitive personal data leaves for a third-party processor. That needs a named processor, a data-processing agreement, a retention rule, and disclosure in the notice — before it is built, not after.
4. Photo protection — what is technically possible, and the layered control that works
Owner requirement: prevent screenshots wherever technically feasible; where it is not reliably supported, display a prominent centred watermark to discourage unauthorised capture, sharing or misuse of personal information and photos.
The instinct is right. An earlier draft of this page dismissed this as "theatre on the web", which was both dismissive and wrong — it named a limitation instead of designing around it, and it missed two controls the platform already has.
What is actually possible, per surface
| Surface | Screenshot prevention | Reality |
|---|---|---|
| Android native | ✅ Real. FLAG_SECURE on the window blocks screenshots and screen recording at OS level | Genuinely effective, free to set |
| iOS native | ❌ No API to prevent | Can only detect after the fact (userDidTakeScreenshotNotification), and detect recording via isCaptured. The isSecureTextEntry layering trick is a hack Apple can break |
| Mobile web | ❌ No API exists. At all. | The OS screenshot is entirely outside the page's control on both iOS Safari and Android Chrome |
⚠ The recipient surface for a shared biodata is mobile web, deliberately — no-install viewing is what makes the growth loop work. So on the surface that matters most, prevention is not available, and the answer has to be layers that work anyway.
The layered control — in order of how much it actually achieves
1. 🔧 Resolution and crop gating — the strongest control, and it works everywhere.
Do not serve a full-resolution photograph to the open tier at all. A small, cropped variant is enough to recognise a person and useless for re-publication elsewhere. Full resolution is released only after the creator approves that recipient.
✅ The platform already models this. packages/data/src/mediaUrl.ts defines MEDIA_VARIANTS with w=/h=/fit= transforms (logo, cover, thumb, og). Adding an open-tier variant is one entry in that map. A screenshot of a 400px crop is a 400px crop — this is the only control here that degrades what a leak is worth.
2. ✅ Short-lived signed media URLs — already built.
_shared/r2.ts presigns with expiresInSeconds, and manage-media already uses a 60-second expiry on one path. Its own header states the principle: "A PRESIGNED URL IS A BEARER TOKEN IN A URL. Anyone holding it can use it until it expires."
This does not stop a screenshot. It stops something else that matters: a recipient copying the image URL and passing the raw asset around, which is the easier and more common leak.
3. 🆕 Per-viewer watermark — attribution, not prevention.
Here is the refinement I would make to the requirement. A prominent centred watermark deters everyone equally and identifies nobody. A per-viewer watermark — the recipient's own name or masked phone number, faint, tiled diagonally across the photograph — does something a centred brand mark cannot:
It converts an unpreventable leak into an attributable one. If a photograph appears somewhere it should not, the watermark says who received it. That is the only mechanism here that changes behaviour rather than merely signalling disapproval, and it is what enterprise document DRM relies on for exactly this reason.
4. 🔮 FLAG_SECURE if a native viewer ever exists. Android only, one flag. Not applicable today because the recipient surface is web.
⚠ The design tension, which is real and needs an explicit decision
A prominent centred watermark degrades the thing the product is selling. The differentiation is a better-looking, more modern presentation than a compressed PDF — families judge on presentation. A heavy mark across a bride's photograph makes it look worse than the artefact it replaces, and the recipient is usually a prospective family, not an adversary.
There is a second, subtler cost. Every recipient — including the mother of a prospective match — is being told, visually and continuously, that they are suspected. That is a tone decision, and it is adjacent to QRS-549's rule about not raising a worry the viewer did not arrive with.
Recommendation: watermark photographs, not the page; per-viewer, not generic; subtle and tiled, not centred and prominent; and pair it with resolution gating, which is doing most of the actual work. If a prominent centred mark is still wanted, make it a creator setting — some families will want maximum deterrence and should be able to choose it, and the ones who want a beautiful profile should not be forced into it.
And the copy rule stays
Whatever is built, the product must never claim photographs cannot be saved, because on the web that is false and a false safety claim is worse than none. Per QRS-549, state what the product does:
- ✅ "Full-size photos are shared only with people you approve." — true, and describes the mechanism
- ✅ "Photos you share carry the viewer's name." — true, and does the deterrent work honestly
- ❌ "Your photos are safe." — a warranty the product cannot keep
5. Fake profiles, and the trust gap
Fake and misrepresented profiles are the most-cited failure of Indian matrimonial platforms. This product amplifies the problem rather than inheriting it, because it optimises for frictionless creation and viral sharing — exactly the conditions impersonation likes.
- ADR-0026 covers vendor verification. There is no equivalent for a person.
- A "Powered by QRSETU" footer on an unverified profile lends the platform's credibility to a claim it has not checked. That is a reputational transfer, and it happens by default.
- Enumerable slugs would let someone harvest profiles at scale — which is an argument for the token-based URL in Architecture fit Decision 1.
Minimum viable trust, if this ships: verified mobile number, rate-limited creation, a visible report control on every public page, and a real takedown path with a named response time.
6. Moderation and takedown have no owner
A public page can carry someone else's photograph, an ex-partner's details, defamatory content, or a profile of a person who never consented. Today there is no moderation queue, no takedown workflow, no appeals path, and no staffing model for any of it.
⚠ This is also an intermediary liability question under the IT Rules: a platform hosting user-generated content needs a grievance officer and defined response timelines to keep safe-harbour protection. That is an operational commitment with a real cost, and it starts on day one of public launch rather than at scale.
7. Commercial and model risks
- Seasonality is not modelled. Indian marriage activity follows the muhurat calendar: heavy November to February and April to June, with a near-dead period during Pitru Paksha. The plan's implied ₹4.17 lakh per month is not a shape revenue will take. Cash-flow planning against a flat average will mislead.
- Assisted profile creation is a services business. ₹299 to ₹999 for a human-built profile carries human unit cost, turnaround-time expectations and quality variance. At the plan's 2,000 units that is a real operational load, and its margin is nothing like software margin.
- The conversion assumption is the load-bearing weakness. See Monetisation.
- Reputational coupling. QRSETU's merchant business and a marriage product share one brand. A safety incident on the consumer side reaches vendor trust, and vice versa. Worth an explicit decision on whether these share a brand at all.
My recommendation
Do not treat this page as a checklist to clear later. Three of these — consent for a non-account subject, the caste-data decision, and the takedown path — are design inputs, not compliance paperwork. Each changes the data model, the screens and the copy. Resolving them after a design round means redoing the design round.
The cheapest possible version of getting this right: decide the default disclosure is closed, make safety controls free, monetise presentation, convenience and reach instead, and put a report control on every public page from the first release.
That costs very little and removes most of the exposure above. Selling privacy costs nothing up front and buys a category of risk that grows with the product's success.