ID
Customer Identity & Access Plan
Recommended identity model

One customer view, one primary Discord identity, multiple billing records.

The cleanest path is to keep the current Airtable, Chargebee, Customer.io, and Discord flows, then add one root Customer Identity Profiles table with a stable profile_id. That profile ties each customer's Chargebee customer records, the billing email on each customer, subscriptions, and access history together. The profile stores one active primary_discord_id for product access, while the billing email on each Chargebee customer stays available for purchases, billing, and recovery.

D
$
👤
Customer
View
Rooted in one profile_id
D
DiscordPrimary product identity
@
Billing emailPurchases and recovery
$
ChargebeeCustomers and subscriptions
AccessRoles and support context
1
Root profile table
A Customer Identity Profile becomes the one record that connects customer identity.
2
Login methods
After purchase, customers are guided to link Discord, with email still available for billing and recovery.
3+
Connected records
Multiple Chargebee customer records, their billing emails, and subscriptions can link to one profile.
Future ready
Built to support support systems, AI, analytics, and engagement tools.
Current problem vs future state

What changes

The goal is not just a nicer login flow. The larger goal is reducing account fragmentation and making access, billing, and support easier to manage.

Today

Different Chargebee billing emails over timeCustomers may create more than one Chargebee customer record by purchasing with different billing emails, which can split their history across records.
💬
Discord and billing can disconnectAccess identity and purchase identity can end up treated like separate customers.
🧩
Manual support workStaff often need to piece together subscriptions, Chargebee customer records, billing emails, and Discord links manually.
Reliability issuesThis can create cancellation issues, entitlement confusion, and more support friction.

Future state

👤
One Customer Identity ProfileA root profile record connects records that belong to the same customer.
🔗
Multiple linked identitiesOne profile can link multiple Chargebee customer records, their billing emails, subscriptions, and one primary Discord account.
🔍
Better visibilityPortal access, subscriptions, support context, and communications are easier to understand in one place.
📈
Growth-ready platformThe structure supports future engagement systems, analytics, and AI features much more cleanly.
Recommended account model

Recommended profile structure

Add one small root table called Customer Identity Profiles. Existing Airtable tables keep their current jobs, but their records link back to that profile. Discord remains the recommended login because the product lives in Discord, while email remains available for billing, purchases, and recovery.
🔑

1. Login flexibility

Customers can log in with Discord or email. Discord is the recommended path for product access, while email remains important for purchases, billing, and recovery.

Discord loginRecommended because the customer experience primarily happens through Discord.
Email loginKeeps billing-related access and account recovery straightforward.
🪪

2. One account record

The Customer Identity Profile becomes the account root. Multiple Chargebee customer records, their billing emails, Discord identity, and subscriptions can all connect without creating fragmentation.

1
Identity profile rootPrevents scattered data across multiple disconnected Chargebee customer records.
2
Linked existing recordsLets the system understand that different Chargebee customer records, including their billing emails, can still belong to the same customer without rebuilding current flows.
🌐

3. Future-ready data model

The current tables stay focused on what they already do, while the profile table gives staff and automation one stable customer record to link back to.

🔗
Backlinked recordsChargebee customer records, their billing emails, subscriptions, Discord identity, and support activity can each link to the same profile row.
🤖
AI-ready contextBecause each activity stream links back to one profile, future automation can understand the full customer picture.
🛡️

Why this matters

This helps reduce missed cancellations, Discord access discrepancies, and support confusion by making the system treat the customer as one person with one primary Discord identity and multiple linked billing records, instead of multiple disconnected Chargebee records.

Identity decision

Discord leads product access, the identity profile keeps history together

Discord should be the strongest matching key and the preferred login because the product is delivered through Discord. The stable account root should be the Customer Identity Profile so billing, recovery, subscriptions, support, and future activity stay connected even when Chargebee billing emails or Discord accounts change. The profile-level primary_discord_id becomes the Discord source of truth; existing customer and subscription Discord fields stay as compatibility fields during migration.

Recommended framing

1
Customer Identity ProfileRoot Airtable record for one real customer, identified by a stable profile_id.
2
Primary Discord IDStored on the Customer Identity Profile as the main product identity for login, access, and role automation.
3
Chargebee billing emailsBilling, purchase, communication, and recovery details stored on Chargebee customer records.
4
Chargebee recordsBilling customers, subscriptions, invoices, and entitlement source data.

Why Discord is not the only root

Purchases can happen firstCheckout usually starts with a Chargebee customer record and billing email before Discord is linked.
Discord can changeIf a customer loses or changes Discord access, the identity profile should survive a support-reviewed replacement.
💳
Billing needs a stable containerInvoices, subscriptions, refunds, and Chargebee customer IDs need to stay connected beyond one Discord account.
Current Discord fields are too narrowChargebee Customers.discord_id belongs to one billing customer row, so it cannot be the long-term source of truth when one person has multiple Chargebee customers.
Current flows still stay compatiblePortal login, webhooks, Customer.io sync, and lifetime handling can keep using current fields while the resolver moves to profile_id and primary_discord_id.
ID

Practical rule

If a Discord ID exists, resolve the Customer Identity Profile from Discord first. If a new purchase creates or uses a different Chargebee customer record or billing email but later links the same Discord ID, attach that Chargebee customer, its billing email, and subscription to the existing profile. If no Discord ID exists yet, create or stage a profile from the Chargebee customer and billing email, then require Discord linking before full product access. A separate Discord linking table is not required because the profile itself stores the one active primary Discord ID.

Primary customer flow

Post-purchase Discord linking resolves the Customer Identity Profile

The standard flow stays the same: the customer buys with a Chargebee billing email, then links Discord for product access. The adjustment is that the system resolves or creates the Customer Identity Profile. If the Discord ID already has a profile, the new Chargebee customer, its billing email, and subscription attach to that same profile. If not, a new profile is created or staged from the current records.
🔗

Recommended post-purchase flow

1

Purchase subscription

The customer buys using a billing email. Chargebee creates the billing customer and subscription.

2

Store billing record

The Chargebee customer and its billing email stay in the existing Chargebee customer and subscription tables.

3

Log in with Discord

Because the product is delivered through Discord, the customer confirms their Discord identity after purchase.

4

Resolve profile

If that Discord ID already has a Customer Identity Profile, reuse it. If not, create one and link the current customer/subscription records.

5

Assign access

The resolved profile groups the active entitlement used to assign the correct Discord access automatically.

Normal successful outcome

1
Discord identity is verifiedThe customer completes Discord login, and the system receives the Discord ID.
2
Profile is reused or createdIf the Discord ID already has a profile, reuse it. If not, create a new Customer Identity Profile.
3
Purchase is attachedThe Chargebee customer, its billing email, and subscription are linked to the resolved profile.
🛡️

How duplicate customer groups are avoided

1
Discord match winsOne Discord ID should point to one Customer Identity Profile. New Chargebee customer records and their billing emails should attach to that same profile.
2
No duplicate profileIf the Discord ID is already known, the system should reuse its profile instead of creating a separate profile for the new Chargebee customer record.
3
Review only for true conflictsSupport review is only needed when the evidence suggests two different Discord users or conflicting account ownership.
🔗

Important rule

One Customer Identity Profile can link multiple Chargebee customer records, their billing emails, and multiple subscriptions, but it should only have one primary Discord ID. The billing email belongs to the Chargebee customer record; it is not a separate standalone email profile. This keeps Discord access clean while preventing Chargebee customer records from becoming the account root.

Required safeguards

What must be included for the approach to work correctly

The profile model works best when existing records are backfilled first, conflicts are handled conservatively, and external systems keep stable identifiers during the transition.
🧱

Migration and backfill

Current Discord-linked users, Chargebee customers and their billing emails, subscriptions, lifetime purchases, and Discord-role access should be reviewed in a dry-run report first, then migrated into Customer Identity Profiles before the new resolver becomes the main path.

1
Run the dry-run reportReview candidates, duplicates, active subscriptions, lifetime records, Discord-native users, and conflicts before writing profile links.
2
Use Discord as the strongest matchExisting Discord IDs should create or resolve the initial profile records.
3
Attach billing recordsKnown Chargebee customer billing emails, Chargebee customer IDs, and subscriptions should link to the resolved profile.
🧭

Conflict review rule

Automatic linking should only happen when the evidence is clear. Unclear ownership should pause the flow instead of merging accounts incorrectly.

Safe to attachOne Chargebee customer/email cluster points to one verified Discord-backed profile.
!
Send to reviewEvidence points to multiple Discord users, multiple owners, or conflicting active access.
📨

Customer.io transition

Customer.io identity should not be changed immediately. The safer first step is to add profile attributes while keeping the current email or Chargebee-based identifiers stable.

1
Add profile attributesSend profile_id and profile summary fields as attributes for segmentation and reporting.
2
Avoid breaking campaignsExisting email-based lifecycle and magic-link flows should continue while profile-aware data is added.
🔐

Discord change and recovery

One active primary Discord ID is still the right access model, but account recovery needs a controlled path when a customer loses or changes Discord accounts.

1
Support-reviewed replacementStaff can replace the primary Discord ID after confirming ownership.
2
Keep the profile stableThe billing records, subscriptions, and history remain intact after the Discord ID changes.
Key table changes

Add one root profile table and link the records that affect identity and access

My recommendation is to keep the implementation focused on the records that solve the current problem: customer identity, billing customers, subscriptions, and Discord access. Other existing support or reporting tables can stay as they are unless a specific workflow needs them later.
Table Current role Implementation change Why it matters
Customer Identity Profiles
New Required
One root record per real customer/account. This is not a Chargebee customer record. profile_id, primary_discord_id, primary_discord_username, preferred_billing_email, profile_status, needs_review_reason, created_at, last_linked_at
Linked records: Chargebee customers, subscriptions, and optional Discord access records.
This gives staff and automation one stable account record while still allowing multiple Chargebee customer records, their billing emails, and multiple subscriptions to belong to the same customer. The primary_discord_id on this table becomes the source of truth for Discord identity.
Chargebee Customers
Core Required
Stores each Chargebee customer, its billing email, name fields, and the current customer-level Discord link used today. Customer Identity Profile
Linked record field; expose profile_id as a lookup/search field. Keep discord_id as a compatibility/reference field during migration.
Multiple Chargebee customer rows can link to the same Customer Identity Profile, which solves the different Chargebee account or billing-email problem without treating a billing record or customer-level discord_id as the root account.
Chargebee Subscriptions
Core Required
Stores subscription, lifetime purchase, plan, Chargebee status, renewal status, Discord role, and entitlement fields. Customer Identity Profile
Linked record field; expose profile_id as a lookup/search field. Keep active_discord_id as a compatibility/reference field during migration.
Upgrade, cancellation, and role-removal checks can look across every subscription linked to the same profile instead of only one Chargebee customer_id.
Discord Role Members
Operational Scope-based
Tracks Discord users, linked Discord IDs, active role state, and any Discord-native access state. Customer Identity Profile
Optional linked record field; add it when Discord-native subscribers or role-state recovery need to be handled through the profile model.
This is not required as the root identity layer. Its value is connecting Discord role state to the same profile used for Chargebee access, so Discord-native access can be checked before roles are assigned or removed.
01

Focused implementation

Create the profile root, backfill the key existing records, and update the resolver used by login, linking, upgrades, cancellations, and role handling. Other tables can receive profile fields later only if a clear operational need appears.

CFG

Build requirements

Add a Customer Identity Profiles table config value, a Customer Identity Profile record type, and Airtable helpers to find or create profiles, attach Chargebee records, and resolve profile-wide access.

!

Why the customer table is not enough

The current customer table represents Chargebee customers. If the same person purchases with two billing emails, Chargebee can create two customer records, so the profile table needs to sit above Chargebee and link those records together.

Recommended flows

How purchases, profiles, and access connect

The existing checkout, Chargebee, Discord login, Customer.io, and role automation flows can stay in place. The main adjustment is resolving the Customer Identity Profile so each flow attaches activity to the correct customer record before access decisions are made.
🧩

Current flows stay, profile checks are added

Current flow What stays the same Profile adjustment
Checkout and purchase Customers still buy with a billing email and Chargebee still creates the billing customer, invoice, and subscription. The Chargebee customer, its billing email, customer ID, and subscription are matched to an existing Customer Identity Profile when possible. If no verified Discord-backed profile exists yet, Discord linking is required before full portal and product access.
Discord OAuth linking Discord remains the preferred product login and the main identity used for access to the Discord-based product. The Discord ID is checked first as the strongest match. If it already belongs to a Customer Identity Profile, new Chargebee customers and their billing emails link to that same profile.
Portal login Customers can still use Discord or email. Email remains useful for login, billing lookup, recovery, and Chargebee purchase history. The portal resolves the profile from Discord ID, the billing email on a Chargebee customer, or Chargebee customer ID. Email-only access can find billing context, but verified Discord is required for full dashboard and product access.
Chargebee webhooks Subscription created, cancelled, renewed, upgraded, and lifetime purchase events still come from Chargebee. Webhook handling writes or resolves the linked profile instead of treating each Chargebee customer or billing email as an isolated account. Entitlement checks use all records linked to the profile.
Discord role handling The existing role assignment and removal automation remains the access mechanism. Before roles are removed, the system checks all linked monthly, yearly, lifetime, and valid Discord-based entitlements on the profile. Access remains if any valid entitlement still exists.
Customer.io sync Customer.io identity should not be changed immediately because that can affect messaging history and automations. Add profile_id and profile summary attributes first. After profile_id is stable, messaging segments can gradually use the grouped data.
Airtable and staff support Airtable can remain the operational view for customers, subscriptions, access, and support checks. Add the Customer Identity Profiles table, then link the key customer, subscription, and Discord access records to it. Current records are backfilled, while conflicting records are sent to review.
🛒

Flow 1: Existing purchase flow with profile matching

1

Purchase with billing email

The customer buys using a billing email. Chargebee creates the billing customer and subscription.

2

Check existing profile

The system checks whether the Chargebee customer, its billing email, or known subscription already links to a Customer Identity Profile.

3

Require Discord if missing

If the resolved profile does not have verified Discord, the customer must link Discord before full dashboard and product access.

4

Attach purchase

The Chargebee customer, its billing email, and subscription link to the resolved Discord-backed profile.

5

Open access

The grouped records now have the billing identity, Discord identity, and active entitlement needed for access.

💬

Flow 2: Existing login flow with profile resolution

1

Customer starts login

Discord is preferred. Email remains available for billing lookup and recovery.

2

Resolve profile

The system finds the Customer Identity Profile from Discord ID first, then email or Chargebee customer when needed.

3

Confirm Discord

If the profile does not have verified Discord yet, the customer completes Discord linking before full access.

4

Open one dashboard

The dashboard can show one account view by loading records linked to the same profile.

🔄

Flow 3: Existing webhook flow with profile-wide entitlements

1
Subscription changesWhen a subscription is cancelled, renewed, upgraded, or changed, the update is applied to records linked to the profile.
2
Check all active accessBefore removing Discord roles, the system checks every monthly, yearly, lifetime, and valid Discord-native entitlement linked to the same profile.
3
Retain or remove rolesIf any valid entitlement remains, access stays. Roles are removed only when the profile has no active subscription, lifetime access, or valid Discord-native access left.
🧑‍💼

Flow 4: Staff support workflow

1
Staff search one profileStaff can search the Customer Identity Profile instead of piecing together disconnected records first.
2
Linked context is visibleChargebee customer records, their billing emails, Discord identity, subscriptions, and future support links can be grouped in one view.
3
Faster support and less confusionThis lowers manual cleanup and makes support much easier.
Scope and decision checks

What should be included in the focused release

The safest version is a focused identity-profile release: add the root table, backfill existing records into profiles, and update access decisions without replacing the current checkout or webhook system.

Core implementation

1
Customer Identity Profiles tableAdd one root table with profile_id, primary Discord ID, optional Discord username, preferred billing email, profile status, and review reason.
2
Migration backfillStart with a dry-run report, then create profiles for current Discord-linked users and link Chargebee customers, subscriptions, and Discord access records.
3
Resolver and entitlement checksResolve the profile before access decisions and check all linked entitlements before removing roles.
4
Customer.io profile attributeSend profile_id and profile summary attributes while keeping current Customer.io identities unchanged.

Defer until needed

1
Customer.io identity migrationDo not change Customer.io identifiers during the focused release.
2
Automated risky mergesDo not auto-merge records when ownership evidence conflicts.
3
Large activity-stream modelSupport, social, analytics, and AI activity can link to profiles later.
4
Custom staff dashboardAirtable can be the first operational view; a custom dashboard can come later if needed.
🧭

Open decisions

1
profile_id formatUse a stable app-generated ID on the Customer Identity Profile, such as cp_ plus a unique value.
2
Billing-email portal accessDecide whether billing-email login can show billing-only details before Discord is linked.
☑️

Acceptance checks

The release is working when a customer with two Chargebee customer records or billing emails and the same Discord ID resolves to one Customer Identity Profile and one profile_id, role removal checks every active monthly, yearly, lifetime, and valid Discord-based entitlement linked to that profile, conflicting ownership goes to review, and Customer.io receives profile_id attributes without changing existing identities.

Further technical notes

Implementation details to confirm before build

These notes are more technical than the main plan. They clarify how the profile resolver, migration, access checks, and external sync should behave.
🧭

Profile resolver by entry point

1
Discord login or linkingUse the verified Discord ID to find Customer Identity Profiles.primary_discord_id first. During migration, current Chargebee customer or subscription Discord fields can be fallback signals and then backfilled to the profile.
2
Chargebee purchase or webhookReuse an existing profile link from the Chargebee customer or subscription first. If none exists, use billing email as supporting evidence and stage the profile until Discord is linked.
3
Billing email is supporting evidenceThe billing email on a Chargebee customer can help match records, but should not auto-merge if ownership is unclear.
4
No separate Discord lookup tableThe profile-level primary_discord_id is enough for the active account lookup; existing verification and audit records keep link history.
!
Review conflictsIf evidence points to multiple Discord users or active owners, stop automatic linking and send it to review.
🧱

Migration and backfill behavior

1
Run a dry-run report firstList profile candidates, duplicates, conflicts, active subscriptions, lifetime records, and Discord-native users before writing profile links.
2
Create profiles from verified Discord linksExisting verified Discord links from current customer/subscription fields are the strongest starting point, then the profile gets the primary_discord_id.
3
Attach billing recordsLink known Chargebee customers and subscriptions to the matching profile.
4
Make it rerunnableThe backfill should be idempotent so it can be rerun safely after fixes or review decisions.
5
Track review stateProfiles should have a clear status for active, needs review, merged, or replaced Discord identity cases.
🔐

Access and entitlement checks

1
Check the whole profileRole assignment/removal should evaluate all subscriptions and valid Discord access linked to the profile.
2
Keep access if any valid entitlement existsMonthly, yearly, lifetime, or valid Discord-native access can keep the required roles active.
3
Remove only when none remainRoles should only be removed when the profile has no active entitlement left.
4
Ignore non-access productsOne-time products that do not grant access should not be treated as lifetime or subscription access.
📨

External sync and operations

1
Customer.io stays stableDo not change Customer.io identity during the focused release; keep the current email or Chargebee-based identifier and add profile_id plus profile summary attributes first.
2
Log link decisionsProfile creation, attachment, conflict, and Discord replacement decisions should be traceable.
3
Support override pathStaff should have a controlled process for review cases and Discord account replacement.
4
Keep current dual writes liveContinue writing the current customer and subscription Discord fields during migration while profile_id and primary_discord_id become the shared resolver keys.
Rollout

Recommended rollout approach

A phased rollout keeps the work practical and cost-conscious: create the profile table first, backfill existing records, then move the highest-risk access checks to the profile model.
🏗️

Phase 1: Add and backfill profiles

Create the Customer Identity Profiles table, then backfill current Discord-linked users, Chargebee customers, subscriptions, and Discord access records while existing flows continue running.

Dry-run and backfill profilesGenerate a review report first, then use existing Discord IDs as the strongest match signal and link known Chargebee customer billing emails, Chargebee customer IDs, and subscriptions to the same profile.
Keep current flows activeCheckout, Chargebee webhooks, Discord linking, role handling, and Customer.io sync keep working while profile links are added behind the scenes.
Review conflictsIf one cluster points to multiple Discord users or conflicting ownership, do not auto-merge it. Send it to support review.
🧭

Phase 2: Portal and access rules

Update portal login, Discord linking, and entitlement checks so access is based on all records linked to the same profile instead of one isolated customer record.

Mandatory Discord linkAllow billing email to find billing records, but require verified Discord before full dashboard and product access.
Profile-wide entitlement checksCheck all monthly, yearly, lifetime, and valid Discord-native access linked to the same profile before assigning or removing roles.
🚀

Phase 3: Support visibility and growth

Once profile links are stable, improve the Airtable views and add richer support or engagement workflows on top of the Customer Identity Profiles table.

Support visibilityShow Discord identity, billing customers, subscriptions, and access status grouped by profile_id.
Smarter engagementUnified customer data enables stronger reporting, automation, and AI use cases later.
💡

Bottom line

This approach solves the account fragmentation problem with the fewest schema changes: keep the current tables, add one Customer Identity Profiles table, link existing records to it, and update the resolver and entitlement checks around that profile.