Spaces:
Sleeping
Sleeping
Download backend/core/constants.py from Success-dev/receipter-pro: direct link, hf CLI and curl.
- Browser
- Download file 8.45 kB
-
https://huggingface.co/spaces/Success-dev/receipter-pro/resolve/main/backend/core/constants.py
- Command line
-
hf download hf://spaces/Success-dev/receipter-pro/backend/core/constants.py
-
curl -L -o constants.py https://huggingface.co/spaces/Success-dev/receipter-pro/resolve/main/backend/core/constants.py
8.45 kB
| """ | |
| Central registry for cross-cutting, iteration-prone values. | |
| This is the ONE place values like these are defined β every other module imports from | |
| here, never hand-copies a number or a list. See docs/blueprint/blueprint.md and | |
| docs/product/checklist.md ("central intelligence... registry") for why this file exists: | |
| these are exactly the values that change a lot across iterations, and a change here should | |
| be a visible, deliberate moment, not a silent edit buried in an unrelated diff. | |
| scripts/run_tests.py diffs this file against the last commit on every test run and prints | |
| a notice (not a failure) listing what changed, so a change here is never silent. | |
| Every value below marked "prototype placeholder" is not a business decision β it exists so | |
| local development and tests have something concrete to run against, and is expected to be | |
| replaced with a real, deliberately-chosen number before Phase 2. | |
| """ | |
| from __future__ import annotations | |
| # --------------------------------------------------------------------------- | |
| # Versioning | |
| # --------------------------------------------------------------------------- | |
| # Application version. Bump on every meaningful release (Phase 4 onward, this drives | |
| # docs/general/CHANGELOG.md entries). | |
| APP_VERSION = "0.1.0-proto" | |
| # Schema version for the data model. Bump when a migration changes stored-data shape in a | |
| # way that old rows won't automatically satisfy β not on every schema tweak. | |
| SCHEMA_VERSION = "0.1.0" | |
| # --------------------------------------------------------------------------- | |
| # Org roles β see docs/blueprint/blueprint.md "Core entities" | |
| # --------------------------------------------------------------------------- | |
| # Ranked low to high. An action gated at a given role is allowed for that role and every | |
| # role ranked above it (e.g. a check gated at "operator" also passes for "admin"/"owner"). | |
| ROLE_RANK: dict[str, int] = { | |
| "viewer": 0, | |
| "operator": 1, | |
| "editor": 1, | |
| "admin": 2, | |
| "owner": 3, | |
| } | |
| # What a role can be allowed to do. Seeing the org's results is not on this list: every | |
| # member can always see them. Labels are shown to owners when they set up a role. | |
| PERMISSIONS: dict[str, str] = { | |
| "edit_lists": "Add and change lists and sign-up forms", | |
| "edit_emails": "Create and change saved emails and looks", | |
| "send": "Send campaigns", | |
| "manage_mailboxes": "Connect and manage mailboxes", | |
| "manage_settings": "Change organisation settings", | |
| "manage_team": "Invite people and change their roles", | |
| } | |
| # Roles every org starts with. Owner always has everything and can't be changed; the | |
| # others are starting points an owner can edit. Custom roles sit beside these. | |
| BUILTIN_ROLES: dict[str, dict] = { | |
| "owner": {"name": "Owner", "permissions": list(PERMISSIONS)}, | |
| "admin": {"name": "Admin", "permissions": list(PERMISSIONS)}, | |
| "editor": {"name": "Editor", "permissions": ["edit_lists", "edit_emails", "send"]}, | |
| "viewer": {"name": "Viewer", "permissions": []}, | |
| } | |
| # Older stored role names, read as their current equivalent. | |
| ROLE_ALIASES: dict[str, str] = {"operator": "editor"} | |
| # Days an invite link stays usable. | |
| INVITE_TTL_DAYS = 7 | |
| # The role assigned automatically to whoever creates an org. Not assignable via | |
| # add_member β ownership only exists by creating the org (transfer is out of scope for now). | |
| ORG_CREATOR_ROLE = "owner" | |
| # --------------------------------------------------------------------------- | |
| # Mailbox connections β see docs/blueprint/adr/0001-relay-not-esp.md | |
| # --------------------------------------------------------------------------- | |
| # Providers that get the OAuth path. Everything else falls through to raw SMTP credentials. | |
| SUPPORTED_OAUTH_PROVIDERS: tuple[str, ...] = ("gmail", "outlook", "yahoo") | |
| # Days between changes to a connected mailbox's sign-in details (a change re-runs the test). | |
| MAILBOX_CREDENTIAL_CHANGE_DAYS = 30 | |
| # Highest daily send limit an org can set on one mailbox. 0 means no limit of our own. | |
| MAILBOX_DAILY_LIMIT_MAX = 10_000 | |
| # Number of OTP verification messages sent in the mailbox-connection round-trip | |
| # (docs/product/srs.md FR-6). | |
| VERIFICATION_OTP_COUNT = 3 | |
| # Seconds to wait for all VERIFICATION_OTP_COUNT messages to arrive before treating the | |
| # connection as a silent failure (SRS FR-7). Prototype placeholder. | |
| VERIFICATION_TIMEOUT_SECONDS = 300 | |
| # --------------------------------------------------------------------------- | |
| # Rate limiting & abuse prevention β see docs/blueprint/blueprint.md "Rate limiting" | |
| # --------------------------------------------------------------------------- | |
| # Default hourly send cap per account, enforced server-side via a rolling token bucket. | |
| # Prototype placeholder β real tiering happens in PLAN_TIERS below once pricing is set. | |
| DEFAULT_HOURLY_SEND_CAP = 100 | |
| # Escalation stages for anomaly detection, in order. Each stage's threshold is a multiple | |
| # of the account's own rolling baseline rate, not an absolute number. | |
| RATE_ANOMALY_ESCALATION_STAGES: tuple[str, ...] = ( | |
| "detect", | |
| "block", | |
| "silently_report", | |
| "auto_temporary_ban", | |
| ) | |
| # --------------------------------------------------------------------------- | |
| # Bounce handling β see docs/blueprint/blueprint.md "Sending pipeline" | |
| # --------------------------------------------------------------------------- | |
| # Soft-bounce retry ceiling before escalating to a person. Prototype placeholder. | |
| SOFT_BOUNCE_RETRY_CEILING = 5 | |
| # Backoff schedule (seconds) between soft-bounce retries, up to the ceiling above. | |
| SOFT_BOUNCE_BACKOFF_SECONDS: tuple[int, ...] = (60, 300, 900, 3600, 14400) | |
| # Initial window (seconds) to match an inbound message to a specific sent OTP/message by | |
| # direct reference before escalating to the broader regex rescan pass. | |
| BOUNCE_MATCH_INITIAL_WINDOW_SECONDS = 120 | |
| # --------------------------------------------------------------------------- | |
| # Billing β see docs/blueprint/adr/0005-per-recipient-pay-as-you-go-billing.md | |
| # --------------------------------------------------------------------------- | |
| # Soft-cap usage warning thresholds, as a fraction of an org's monthly free allowance. | |
| # Fires on all 3 surfaces (email, in-app, control panel banner) per SRS FR-28. | |
| SOFT_CAP_WARNING_THRESHOLDS: tuple[float, ...] = (0.8, 1.0) | |
| # Plan tiers. Real pricing/allowances are a business decision (see ADR-0005) β these are | |
| # structural placeholders so the billing code has real shapes to run tests against. | |
| PLAN_TIERS: dict[str, dict[str, object]] = { | |
| "free": { | |
| "monthly_recipient_allowance": 500, # prototype placeholder | |
| "hourly_send_cap": DEFAULT_HOURLY_SEND_CAP, | |
| "storage_mb": 250, # prototype placeholder | |
| "overage_allowed": False, | |
| }, | |
| "paid": { | |
| "monthly_recipient_allowance": None, # unlimited within pay-as-you-go | |
| "hourly_send_cap": DEFAULT_HOURLY_SEND_CAP * 5, # prototype placeholder | |
| "storage_mb": 5000, # prototype placeholder | |
| "overage_allowed": True, | |
| }, | |
| } | |
| # --------------------------------------------------------------------------- | |
| # M8ion's own outbound identity β see docs/blueprint/blueprint.md "M8ion's own outbound mail" | |
| # --------------------------------------------------------------------------- | |
| # Prototype-only sending address for M8ion's own transactional mail. Replaced with a real | |
| # registered domain before Phase 3. | |
| SYSTEM_SENDER_ADDRESS_PROTO = "projects.techies.26@gmail.com" | |
| # The receiving side of the mailbox-verification round-trip (SRS FR-6) β "M8ion's own test | |
| # mailbox". Prototype placeholder; becomes a real address once a domain is registered. | |
| SYSTEM_TEST_MAILBOX_ADDRESS_PROTO = "verify-test@m8ion-test.local" | |
| # --------------------------------------------------------------------------- | |
| # Public collection endpoint (docs/blueprint/adr/0006) β all prototype placeholders | |
| # --------------------------------------------------------------------------- | |
| COLLECT_MAX_BODY_BYTES = 8_000 | |
| COLLECT_MAX_FIELDS = 30 | |
| COLLECT_MAX_VALUE_LENGTH = 500 | |
| COLLECT_MIN_FILL_SECONDS = 2 # a human cannot fill a form faster than this | |
| COLLECT_PER_KEY_PER_MINUTE = 30 | |
| COLLECT_PER_IP_PER_MINUTE = 10 | |
| COLLECT_PER_ADDRESS_PER_HOUR = 1 # confirmation emails to one address, per key | |
| COLLECT_DEFAULT_DAILY_CAP = 500 | |
| COLLECT_CONFIRM_TTL_HOURS = 48 | |
| # Field names that are never collected, whatever the key allows. | |
| COLLECT_BLOCKED_FIELD_WORDS = ("password", "passwd", "pwd", "card", "cvv", "cvc", "ssn", "secret", "token") | |