new-site/scripts/formation/states/bc/config.py
justin f8cd37ac8c Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 06:54:22 -05:00

615 lines
34 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Configuration for British Columbia, Canada — BC Business Corporations Act.
BC uses a provincial incorporation system (not federal), governed by the
BC Business Corporations Act (SBC 2002, c. 57). Entities formed here are
BC corporations — LLCs do not exist under Canadian law.
Portal stack:
- Corporate Online (corporateonline.gov.bc.ca) — filing & annual reports
NOTE: No login required for new incorporations — the wizard is anonymous
and payment is taken by credit card at the end. Do NOT attempt username/
password auth — the login page is IDIR-only (government employees).
- BC Registry Name Request (bcregistrynames.gov.bc.ca) — name reservation
- Anytime Mailbox (anytimemailbox.com) — virtual mailbox for registered office
- CRTC — Canadian Radio-television and Telecommunications Commission
(requires notification letter for telecom carriers)
Currency: all fees in CAD (C$).
COLIN wizard steps (in order):
1. Initial Information — company name / effective date
2. Incorporator Info — incorporator name + address
3. Completing Party — person completing the filing
4. Translated Name — (skip — not applicable)
5. Director Info — director name(s) + address(es)
6. Office Addresses — registered office + records office
7. Share Structure — share classes (Common shares, no par value)
8. Notification — email for receipt
9. Company Information — confirm name + type
10. Confirm Company Info — review everything
11. Ready to Pay — credit card entry
12. Your Receipt — BC incorporation number
"""
CONFIG = {
"jurisdiction": "British Columbia",
"country": "Canada",
"abbreviation": "BC",
"entity_types": ["corporation"], # No LLCs in Canada
# ------------------------------------------------------------------ #
# Portal schedule — BC Corporate Online hours + BC holidays
# MonSat 6 AM 10 PM, Sun 1 PM 10 PM Pacific
# ------------------------------------------------------------------ #
"portal_schedule": {
"timezone": "America/Vancouver",
"jurisdiction": "BC",
"closed_holidays": True,
"hours": {
"mon": [6, 22],
"tue": [6, 22],
"wed": [6, 22],
"thu": [6, 22],
"fri": [6, 22],
"sat": [6, 22],
"sun": [13, 22],
},
},
# ------------------------------------------------------------------ #
# BC Registry — Corporate Online
# No authentication required — anonymous public filing portal.
# ------------------------------------------------------------------ #
"agency": "BC Registry Services",
"agency_url": "https://www.bcregistry.gov.bc.ca",
"filing_portal": {
"name": "Corporate Online",
"url": "https://www.corporateonline.gov.bc.ca",
# Direct URL to start a new Incorporation Application (anonymous)
"icorp_start_url": "https://www.corporateonline.gov.bc.ca/corporateonline/colin/accesstransaction/menu.do?action=startFiling&filingTypeCode=ICORP&from=main",
"icorp_overview_url": "https://www.corporateonline.gov.bc.ca/corporateonline/colin/accesstransaction/menu.do?action=overview&filingTypeCode=ICORP&from=main",
# Annual report
"annual_report_url": "https://www.corporateonline.gov.bc.ca/corporateonline/colin/accesstransaction/menu.do?action=startFiling&filingTypeCode=ANNBC&from=main",
# Legacy — kept for compat; IDIR-only now (not used for automation)
"login_url": "https://www.corporateonline.gov.bc.ca/corporateonline/colin/login/login.do",
},
"name_request_portal": {
"name": "BC Registry Name Request",
"url": "https://www.bcregistrynames.gov.bc.ca",
"search_url": "https://www.bcregistrynames.gov.bc.ca/nrSearch/name-search",
},
# ------------------------------------------------------------------ #
# Registered & Records Office — Anytime Mailbox (BC locations)
# ------------------------------------------------------------------ #
"registered_office_default": "victoria-dr",
"registered_office_locations": {
"victoria-dr": {
"id": "victoria-dr",
"label": "Vancouver - Victoria Dr (Best Value)",
"street": "5307 Victoria Dr",
"suite_prefix": "Suite",
"city": "Vancouver",
"province": "BC",
"postal_code": "V5P 3V6",
"country": "Canada",
"plan": "Basic",
"plan_cost_cad": 99.00,
"plan_period": "yearly",
"default": True,
},
"howe-st": {
"id": "howe-st",
"label": "Vancouver - Howe St (Downtown)",
"street": "329 Howe St",
"suite_prefix": "Unit",
"city": "Vancouver",
"province": "BC",
"postal_code": "V6C 3N2",
"country": "Canada",
"plan": "Silver",
"plan_cost_cad": 164.99,
"plan_period": "yearly",
"default": False,
},
"broadway": {
"id": "broadway",
"label": "Vancouver - Broadway",
"street": "1275 W Broadway",
"suite_prefix": "Suite",
"city": "Vancouver",
"province": "BC",
"postal_code": "V6H 1G2",
"country": "Canada",
"plan": "Silver",
"plan_cost_cad": 149.99,
"plan_period": "yearly",
"default": False,
},
},
# Legacy field — kept for backward compatibility
"registered_office": {
"provider": "Anytime Mailbox",
"provider_url": "https://www.anytimemailbox.com",
"location": "Vancouver - Victoria Dr",
"street": "5307 Victoria Dr",
"city": "Vancouver",
"province": "BC",
"postal_code": "V5P 3V6",
"country": "Canada",
"plan": "Basic",
"plan_cost_cad": 99.00,
"plan_period": "yearly",
},
# ------------------------------------------------------------------ #
# CRTC
# ------------------------------------------------------------------ #
"crtc": {
"name": "Canadian Radio-television and Telecommunications Commission",
"short_name": "CRTC",
"secretary_general": "Secretary General, CRTC",
"address": "1 Promenade du Portage",
"city": "Gatineau",
"province": "QC",
"postal_code": "J8X 4B1",
"country": "Canada",
"website": "https://crtc.gc.ca",
"notification_required": True,
},
# ------------------------------------------------------------------ #
# BITS (Basic International Telecommunications Services)
# ------------------------------------------------------------------ #
"bits": {
"name": "BITS Registration",
"description": (
"All Canadian telecom carriers must register with the CRTC "
"under the Basic International Telecommunications Services (BITS) regime. "
"Registration is filed via letter to the CRTC Secretary General."
),
"filing_method": "letter", # submitted with the CRTC notification letter
"annual_fee_cad": 0.00, # no fee for initial BITS notification
"renewal_required": False, # initial registration is a one-time notification
},
# ------------------------------------------------------------------ #
# CCTS (Commission for Complaints for Telecom-television Services)
# ------------------------------------------------------------------ #
"ccts": {
"name": "Commission for Complaints for Telecom-television Services",
"short_name": "CCTS",
"website": "https://www.ccts-cprst.ca",
"membership_url": "https://www.ccts-cprst.ca/for-service-providers/become-a-member/",
"description": (
"All Canadian telecom service providers must participate in the CCTS, "
"the national and independent organization dedicated to resolving "
"customer complaints about telecom and TV services. "
"Membership application is submitted online."
),
"filing_method": "online_form",
"annual_fee_cad": 0.00, # no fee for small carriers in first year
"renewal_required": True,
"renewal_period": "Yearly",
},
# ------------------------------------------------------------------ #
# GCKey — Government of Canada authentication credential
# Used to access My CRTC Account for electronic filings.
# Each carrier gets its own GCKey. Signup is a 5-step Spring Web Flow
# wizard with hCaptcha invisible on the username step.
# ------------------------------------------------------------------ #
"gckey": {
"name": "GCKey",
"description": "Government of Canada authentication credential for online services",
"homepage": "https://www.gckey.gc.ca",
"auth_domain": "clegc-gckey.gc.ca",
# SAML entry: go through CRTC SmartForms → GACS → GCKey
"saml_entry_url": "https://services.crtc.gc.ca/Pro/SmartForms/?_gc_lang=eng",
"signup_path": "/j/eng/rg", # append ?ReqID=... from SAML flow
# Signup wizard — 5 steps (Spring Web Flow)
"signup_steps": {
# Step 1: Terms and Conditions
"terms": {
"execution": "e1s1",
"accept_btn": "input[name=_eventId_accept]",
"decline_btn": "input[name=_eventId_cancel]",
},
# Step 2: Create Username
"username": {
"execution": "e1s2",
"field": "input[name=uid][id=userID]",
"submit_btn": "input[name=_eventId_submit][id=button]",
"hcaptcha_sitekey": "99871bd1-7b22-417a-b6cc-7ef645e5147a",
},
# Step 3: Create Password (selectors to be verified on first live run)
"password": {
"execution": "e1s3", # inferred — may be e1s3 or later
"field": "input[type=password][name=pwd]", # inferred
"confirm_field": "input[type=password][name=confirmPwd]", # inferred
"submit_btn": "input[name=_eventId_submit]",
},
# Step 4: Recovery Questions
"security_questions": {
"execution": "e1s4", # inferred
"question_selects": "select", # multiple <select> elements
"answer_inputs": "input[type=text]", # answer fields
"submit_btn": "input[name=_eventId_submit]",
},
# Step 5: Recovery Email (to be verified)
"email": {
"execution": "e1s5", # inferred
"field": "input[type=email], input[name=email]", # inferred
"submit_btn": "input[name=_eventId_submit]",
},
},
# Login page — used after account creation to verify the credentials work
"login_selectors": {
"username": "input[name=token1][id=token1]",
"password": "input[name=token2][id=token2]",
"signin_btn": "button[id=button]",
"csrf": "input[name=_csrf]",
"hcaptcha_sitekey": "c745648c-d973-4223-99af-8d178dc17a6c",
},
# Username format: pw-{bc_number} — deterministic per carrier
"username_prefix": "pw-",
# Password rules (from GCKey help page — to be verified)
"password_rules": {
"min_length": 8,
"max_length": 16,
"require_upper": True,
"require_lower": True,
"require_digit": True,
"require_special": True,
},
},
# ------------------------------------------------------------------ #
# ATS — CRTC Annual Telecommunications Survey
# All registered carriers must file annually via My CRTC Account (GCKey).
# ------------------------------------------------------------------ #
"ats": {
"name": "CRTC Annual Telecommunications Survey",
"portal_url": "https://services.crtc.gc.ca/Pro/SmartForms/?_gc_lang=eng",
"gckey_url": "https://www.gckey.gc.ca",
"my_crtc_url": "http://crtc.gc.ca/eng/forms/form_index.htm",
# Activation code: required for first electronic submission.
# Obtained by calling CRTC at 1-877-249-2782 or included in
# registration confirmation letter (30-60 days after filing).
"activation_code_phone": "1-877-249-2782",
"forms": {
"rep_t1": {
"name": "REP-T/T1 — Annual Telecommunications Survey",
"description": "Core annual survey for all telecom service providers",
"deadline_month": 3,
"deadline_day": 1,
"threshold": "All registered carriers must file — no revenue threshold",
"required_for_new_carriers": True,
},
"rep_u": {
"name": "REP-U — Universal Broadband Fund Survey",
"description": "Survey for carriers participating in broadband fund",
"deadline_month": 3,
"deadline_day": 31,
"threshold": "Carriers with >$10M CAD annual Canadian telecom revenue",
"required_for_new_carriers": False,
},
"form_802a": {
"name": "Form 802a — Contribution Survey",
"description": "Annual contribution obligation calculation",
"deadline_month": 3,
"deadline_day": 31,
"threshold": "Carriers with >$10M CAD annual Canadian telecom revenue",
"required_for_new_carriers": False,
},
"form_802j": {
"name": "Form 802j — Contribution Eligibility Survey",
"description": "For carriers seeking subsidy eligibility under the national contribution fund",
"deadline_month": 3,
"deadline_day": 31,
"threshold": "Only carriers seeking contribution fund subsidy eligibility",
"required_for_new_carriers": False,
},
},
"related_surveys": {
"facilities": {
"name": "Annual Facilities Survey",
"description": "Network infrastructure details for carriers owning/operating telecom facilities",
"deadline_month": 3,
"deadline_day": 31,
"threshold": "Carriers owning or operating telecom network facilities",
"required_for_new_carriers": False,
},
"pricing": {
"name": "Annual Communications Pricing Survey",
"description": "Pricing data for telecom services offered",
"deadline_month": 3,
"deadline_day": 31,
"threshold": "Carriers with >$10M CAD annual Canadian telecom revenue",
"required_for_new_carriers": False,
},
},
},
# ------------------------------------------------------------------ #
# BC Corporate Tax & Filing Obligations
# Assumes calendar fiscal year-end (Dec 31). If the client chooses a
# non-standard fiscal year, these dates need adjustment.
# ------------------------------------------------------------------ #
"corporate_obligations": {
"t2_return": {
"name": "Federal T2 Corporate Income Tax Return",
"description": (
"All Canadian corporations must file a T2 return with the CRA, "
"even if there is no tax owing or no business activity. "
"Filed electronically via CRA My Business Account or certified tax software."
),
"deadline_description": "6 months after fiscal year-end",
"deadline_month": 6, # June 30 for Dec 31 year-end
"deadline_day": 30,
"required": True,
"penalty": "5% of unpaid tax + 1%/month for up to 12 months",
"cra_url": "https://www.canada.ca/en/revenue-agency/services/tax/businesses/topics/corporations/corporation-income-tax-return.html",
},
"t2_tax_payment": {
"name": "Federal/Provincial Corporate Tax Payment",
"description": (
"Corporate income tax balance owing is due earlier than the T2 return. "
"For Canadian-Controlled Private Corporations (CCPCs) with taxable income "
"under $500K, payment is due 3 months after year-end. "
"Interest accrues on late payments."
),
"deadline_description": "3 months after fiscal year-end (CCPCs under $500K)",
"deadline_month": 3, # March 31 for Dec 31 year-end
"deadline_day": 31,
"required": True,
},
"gst_hst_return": {
"name": "GST/HST Return",
"description": (
"If registered for GST/HST (required if revenue > $30K/yr, "
"recommended to register voluntarily for input tax credits). "
"Annual filers: due 3 months after fiscal year-end. "
"Telecom services are generally GST/HST taxable."
),
"deadline_description": "3 months after fiscal year-end (annual filers)",
"deadline_month": 3, # March 31 for Dec 31 year-end
"deadline_day": 31,
"threshold": "Mandatory if >$30K revenue; voluntary registration recommended",
"required_for_new_carriers": True, # should register voluntarily
},
"t4_t4a_slips": {
"name": "T4/T4A Information Slips",
"description": (
"If the corporation has employees or contractors paid >$500/yr, "
"T4 (employment) and/or T4A (contractor) slips must be filed. "
"Not applicable for most new shell telecom corporations."
),
"deadline_description": "Last day of February following the calendar year",
"deadline_month": 2,
"deadline_day": 28,
"threshold": "Only if corporation has employees or pays contractors >$500/yr",
"required_for_new_carriers": False,
},
"bc_pst": {
"name": "BC Provincial Sales Tax (PST) Return",
"description": (
"Most telecom services in BC are subject to 7% PST. "
"If registered as a PST collector, returns are due monthly, "
"quarterly, or annually depending on volume. "
"New carriers should consult with an accountant about PST obligations."
),
"threshold": "If collecting PST on taxable telecom services",
"required_for_new_carriers": False, # depends on service type
},
"worksafebc": {
"name": "WorkSafeBC Annual Return",
"description": (
"Required if the corporation has employees in BC. "
"Annual return reports payroll for workers' compensation premium calculation. "
"Not applicable for corporations with no employees."
),
"deadline_description": "March 1 following the calendar year",
"deadline_month": 3,
"deadline_day": 1,
"threshold": "Only if corporation has BC employees",
"required_for_new_carriers": False,
},
"crtc_registration_update": {
"name": "CRTC Annual Registration Update",
"description": (
"The CRTC contacts registered carriers annually to verify and update "
"registration information. Must respond to maintain active registration status. "
"The CRTC initiates this — you just need to respond."
),
"deadline_description": "Respond within 30 days of CRTC contact (typically Q1)",
"required": True,
},
},
# ------------------------------------------------------------------ #
# Fees (CAD)
# ------------------------------------------------------------------ #
"fees": {
"name_reservation": 30.00,
"incorporation": 350.00,
"annual_report": 42.00,
"mailbox_yearly": 164.99,
"currency": "CAD",
},
# ------------------------------------------------------------------ #
# Playwright selectors — BC Corporate Online (Struts / classic HTML)
#
# IMPORTANT NOTES ON THE PORTAL:
# - No login required for Incorporation Application (anonymous filing)
# - All form fields follow Struts DTO naming: fedDto.*
# - Wizard is a multi-page POST flow; Playwright must follow the
# "Next" / "Continue" buttons between pages
# - Payment is by credit card — use Relay virtual debit card
# - After payment, the BC incorporation number appears on the receipt
#
# Selector status:
# ✓ CONFIRMED from live portal HTML (fetched 2026-04-04)
# ~ INFERRED from Struts DTO naming convention + wizard step structure
# ✗ UNVERIFIED — needs manual inspection in a live session
# ------------------------------------------------------------------ #
"selectors": {
# ── Step 0: No login required ────────────────────────────────────
# Navigate directly to icorp_start_url (anonymous)
"login_username": "", # Not used — portal is anonymous
"login_password": "", # Not used
"login_submit": "", # Not used
# ── Step 1: Initial Information ──────────────────────────────────
# URL: .../menu.do?action=startFiling&filingTypeCode=ICORP&from=main
# Confirmed from live HTML fetch 2026-04-04:
# - Radio button for numbered company: value="NMBRD"
# - Name reservation number input field is present
# - Effective date selects: fedDto.effectiveDateTime.*
"inc_numbered_company_radio": "input[type='radio'][value='NMBRD']", # ✓ confirmed
"inc_nr_number": "input[name='fedDto.nameReservationNumber']", # ~ inferred
"inc_effective_immediately": "input[type='radio'][value='immediate']", # ~ inferred
"inc_next_btn": "input[type='submit'][value='Next >']", # ~ inferred
# ── Step 2: Incorporator Info ────────────────────────────────────
# Who is incorporating the company. We list Performance West Inc.
# as the incorporator (agent on behalf of client).
"inc_incorporator_first": "input[name='fedDto.incorporatorDto.firstName']", # ~ inferred
"inc_incorporator_last": "input[name='fedDto.incorporatorDto.lastName']", # ~ inferred
"inc_incorporator_org": "input[name='fedDto.incorporatorDto.orgName']", # ~ inferred (org name)
"inc_incorporator_addr1": "input[name='fedDto.incorporatorDto.address.addr1']", # ~ inferred
"inc_incorporator_city": "input[name='fedDto.incorporatorDto.address.city']", # ~ inferred
"inc_incorporator_prov": "select[name='fedDto.incorporatorDto.address.province']", # ~ inferred
"inc_incorporator_postal":"input[name='fedDto.incorporatorDto.address.postalCd']", # ~ inferred
"inc_incorporator_country":"select[name='fedDto.incorporatorDto.address.country']", # ~ inferred
# ── Step 3: Completing Party ─────────────────────────────────────
# Person completing this filing (same as incorporator for us).
"inc_completing_same_chk": "input[type='checkbox'][name*='sameasincorporator' i]", # ~ inferred
"inc_completing_first": "input[name='fedDto.completingPartyDto.firstName']", # ~ inferred
"inc_completing_last": "input[name='fedDto.completingPartyDto.lastName']", # ~ inferred
"inc_completing_phone": "input[name='fedDto.completingPartyDto.phoneNumber']", # ~ inferred
"inc_completing_email": "input[name='fedDto.completingPartyDto.email']", # ~ inferred
# ── Step 5: Director Info ────────────────────────────────────────
# Director 1 (the client is typically sole director)
# These are the UNVERIFIED selectors flagged in adapter.py.
"inc_director_name": "input[name='fedDto.directorDtos[0].fullName']", # ✗ unverified
"inc_director_first": "input[name='fedDto.directorDtos[0].firstName']", # ✗ unverified
"inc_director_last": "input[name='fedDto.directorDtos[0].lastName']", # ✗ unverified
"inc_director_addr1": "input[name='fedDto.directorDtos[0].address.addr1']", # ✗ unverified
"inc_director_city": "input[name='fedDto.directorDtos[0].address.city']", # ✗ unverified
"inc_director_prov": "select[name='fedDto.directorDtos[0].address.province']",# ✗ unverified
"inc_director_postal": "input[name='fedDto.directorDtos[0].address.postalCd']", # ✗ unverified
"inc_director_country": "select[name='fedDto.directorDtos[0].address.country']", # ✗ unverified
# Legacy combined field (some COLIN versions use a single fullName input)
"inc_director_address": "input[name='fedDto.directorDtos[0].address.addr1']", # ✗ unverified
# ── Step 6: Office Addresses ─────────────────────────────────────
# Registered office = Anytime Mailbox address + unit number
"inc_registered_office_street": "input[name='fedDto.regOfficeDto.deliveryAddress.addr1']", # ✗ unverified
"inc_registered_office_city": "input[name='fedDto.regOfficeDto.deliveryAddress.city']", # ✗ unverified
"inc_registered_office_province":"select[name='fedDto.regOfficeDto.deliveryAddress.province']", # ✗ unverified
"inc_registered_office_postal": "input[name='fedDto.regOfficeDto.deliveryAddress.postalCd']", # ✗ unverified
# Records office same as registered — typical checkbox
"inc_records_office_same": "input[type='checkbox'][name*='recordsSame' i]", # ✗ unverified
# company_name is shown as a label here; not a text input at this step
"inc_company_name": "input[name='fedDto.nameReservationNumber']", # only for NR# path
# ── Step 7: Share Structure ──────────────────────────────────────
# Standard structure: 1 class, "Common Shares", unlimited, no par value
# COLIN presents a pre-filled Table 1 Articles option (checkbox to adopt)
"inc_share_structure": "input[type='checkbox'][name*='adoptTable1' i]", # ✗ unverified
"inc_table1_adopt": "input[type='checkbox'][name*='adoptTable1' i]", # ✗ unverified
"inc_share_class_name": "input[name='fedDto.shareDtos[0].className']", # ✗ unverified
"inc_share_max": "input[name='fedDto.shareDtos[0].maxShares']", # ✗ unverified
# Articles file upload — only needed if NOT using Table 1
"inc_articles": "input[type='file'][name*='articles' i]", # ✗ unverified
# ── Step 8: Notification ─────────────────────────────────────────
"inc_notification_email": "input[name='fedDto.notificationEmail']", # ~ inferred
# ── Step 11: Ready to Pay (credit card) ──────────────────────────
# COLIN uses a standard card form at checkout
"pay_card_number": "input[name='cardNumber'], input[id*='cardNumber' i], input[autocomplete='cc-number']", # ✗ unverified
"pay_card_exp": "input[name='expiryDate'], input[id*='expiry' i], input[autocomplete='cc-exp']", # ✗ unverified
"pay_card_cvv": "input[name='cvv'], input[name='cvd'], input[id*='cvv' i], input[autocomplete='cc-csc']", # ✗ unverified
"pay_card_name": "input[name='cardholderName'], input[id*='cardHolder' i], input[autocomplete='cc-name']", # ✗ unverified
"pay_submit": "input[type='submit'][value*='Pay' i], button:has-text('Pay Now'), input[type='submit'][value*='Submit Payment' i]", # ✗ unverified
# ── Step 12: Submit / Confirmation ───────────────────────────────
"inc_submit": "input[type='submit'][value*='Submit' i], input[type='submit'][value*='Confirm' i]", # ✗ unverified
# Confirmation / receipt page — BC incorporation number
"inc_confirmation_number": ".confirmation-number, td:has-text('Incorporation Number') + td, td.dataValue", # ✗ unverified
# ── Name Request portal (bcregistrynames.gov.bc.ca) ──────────────
# Modern Vue.js SPA — selectors are data-test or aria attributes
"name_search_input": "input[id='business-name'], input[placeholder*='Enter name' i], input[data-test='business-name']", # ~ inferred
"name_search_submit": "button[data-test='search-btn'], button:has-text('Search')", # ~ inferred
"name_result_available": ".v-chip--label:has-text('Available'), .available-badge, [class*='available']", # ~ inferred
"name_result_unavailable":"[class*='not-available'], [class*='unavailable'], .v-chip:has-text('Not Available')", # ~ inferred
"name_reserve_btn": "button:has-text('Reserve'), button[data-test='reserve-btn']", # ~ inferred
# ── Anytime Mailbox ───────────────────────────────────────────────
"amb_location_search": "input[placeholder*='city' i], input[placeholder*='search' i]",
"amb_email": "input[type='email'], input[name*='email' i]",
"amb_password": "input[type='password'], input[name*='password' i]",
"amb_phone": "input[type='tel'], input[name*='phone' i]",
"amb_first_name": "input[name*='firstName' i], input[name*='first_name' i], input[placeholder*='First name' i]",
"amb_last_name": "input[name*='lastName' i], input[name*='last_name' i], input[placeholder*='Last name' i]",
"amb_business_name": "input[name*='business' i], input[placeholder*='Business name' i]",
"amb_home_address": "input[name*='address' i]:not([name*='email' i]), input[placeholder*='Street' i]",
"amb_home_city": "input[name*='city' i]",
"amb_home_state": "select[name*='state' i], select[name*='province' i]",
"amb_home_postal": "input[name*='postal' i], input[name*='zip' i]",
"amb_plan_select": "button:has-text('Select'), a:has-text('Select')",
"amb_plan_period_yearly": "input[type='radio'][value*='year' i], label:has-text('Yearly')",
"amb_location_select": "button:has-text('Choose'), button:has-text('Select this location')",
"amb_mailbox_number_first":"select option:first-child, .mailbox-select option:nth-child(2)",
"amb_continue": "button:has-text('Continue'), button:has-text('Next')",
"amb_otp": "input[name*='otp' i], input[name*='code' i], input[placeholder*='verification' i]",
"amb_otp_submit": "button:has-text('Verify'), button:has-text('Submit')",
"amb_checkout_submit": "button:has-text('Complete'), button:has-text('Subscribe'), button:has-text('Pay')",
# ── Annual Report ─────────────────────────────────────────────────
"ar_filing_year": "select[name*='year' i], input[name*='year' i]",
"ar_confirm_address": "input[type='checkbox'][name*='confirm' i]",
"ar_submit": "input[type='submit'], button[type='submit']",
},
# ------------------------------------------------------------------ #
# Selector verification status
# Tracks which step selectors have been confirmed against the live portal.
# The adapter checks this before running to prevent half-complete filings.
# ------------------------------------------------------------------ #
"COLIN_UNVERIFIED_STEP_SELECTORS": {
# Steps 5-12 need live session verification.
# Remove a step once confirmed to unblock that part of the pipeline.
5: ["inc_director_first", "inc_director_last", "inc_director_addr1"],
6: ["inc_registered_office_street", "inc_records_office_same"],
7: ["inc_share_structure", "inc_table1_adopt"],
9: ["pay_card_number", "pay_card_exp", "pay_card_cvv", "pay_submit"],
12: ["inc_submit", "inc_confirmation_number"],
},
# ------------------------------------------------------------------ #
# Notes
# ------------------------------------------------------------------ #
"notes": (
"BC Business Corporations Act (SBC 2002, c. 57) requirements:\n"
" - Must have at least one director (can be non-resident).\n"
" - Registered office AND records office must be in BC.\n"
" - We use Anytime Mailbox at client's chosen BC location as both.\n"
" - Name reservation is optional but recommended (valid 56 days).\n"
" - Numbered companies do not require a name reservation.\n"
" - Annual Report due within 2 months of anniversary date.\n"
" - CRTC notification required for telecom service providers.\n"
" - All fees in Canadian Dollars (CAD).\n"
" - Corporate Online filing portal is ANONYMOUS — no login required.\n"
" Payment by Visa/MC/Amex at the end of the wizard.\n"
" Use Relay virtual debit card (SID-0002) for filing payment."
),
}