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>
This commit is contained in:
justin 2026-04-27 06:54:22 -05:00
commit f8cd37ac8c
1823 changed files with 145167 additions and 0 deletions

View file

@ -0,0 +1,4 @@
from .config import CONFIG
from .adapter import TXPortal
__all__ = ["CONFIG", "TXPortal"]

View file

@ -0,0 +1,205 @@
"""Texas — SOSDirect SOS portal automation.
SOSDirect (direct.sos.state.tx.us) is the Texas Secretary of State's
online filing system. It requires an account login. Name search is
available without login via the Comptroller's Taxable Entity Search.
Key URLs:
Name search: https://mycpa.cpa.state.tx.us/coa/Index.html
SOSDirect: https://direct.sos.state.tx.us
Filing: SOSDirect Corporations File a Certificate of Formation
Fees:
LLC: $300 (Certificate of Formation Domestic LLC)
Corp: $300 (Certificate of Formation Domestic Corp)
Expedited: +$25 (24-hour), +$50 (same-day)
Notes:
- Texas uses "Certificate of Formation" (not Articles of Organization)
- No publication requirement
- Franchise tax applies only if revenue > $2.47M (most small carriers exempt)
- SOSDirect uses ASP.NET with __VIEWSTATE like WY; human-pace typing required
"""
from __future__ import annotations
import asyncio
import re
from typing import Optional
from scripts.formation.base import (
StatePortal,
NameSearchResult,
FormationOrder,
FilingResult,
FilingStatus,
EntityType,
)
from .config import CONFIG
class TXPortal(StatePortal):
STATE_CODE = "TX"
STATE_NAME = "Texas"
PORTAL_NAME = "SOSDirect"
PORTAL_URL = "https://direct.sos.state.tx.us"
NWRA_ADDRESS = CONFIG["registered_agent"]["street"]
NWRA_CITY = CONFIG["registered_agent"]["city"]
NWRA_STATE = CONFIG["registered_agent"]["state"]
NWRA_ZIP = CONFIG["registered_agent"]["zip"]
# ── Name Search (Comptroller Taxable Entity Search — no login) ──────
async def search_name(self, name: str) -> NameSearchResult:
"""Search Texas business name availability via the Comptroller
Taxable Entity Search (free, no login required).
URL: https://mycpa.cpa.state.tx.us/coa/Index.html
This searches the Comptroller's database, not the SOS. A name
can be "available" in the Comptroller DB but reserved at SOS.
For definitive availability, SOSDirect's name check is better —
but requires login. We check Comptroller first (free + fast),
then flag for SOSDirect confirmation if the customer proceeds.
"""
try:
page = await self.start_browser()
await page.goto(
"https://mycpa.cpa.state.tx.us/coa/Index.html",
wait_until="networkidle",
)
await self.human_delay(1.0, 2.0)
# The Comptroller search page has a text input + search button
# Selector: input field for entity name
await page.fill(
'input[name="entityName"], input#entityName, input[type="text"]',
"",
)
await self.type_slowly(
page,
'input[name="entityName"], input#entityName, input[type="text"]',
name,
)
await self.human_delay(0.5, 1.0)
# Click search
await page.click(
'input[type="submit"], button[type="submit"], '
'#searchButton, input[value="Search"]'
)
await page.wait_for_load_state("networkidle")
await self.human_delay(1.0, 2.0)
# Parse results
content = await page.content()
await self.screenshot(page, f"tx_name_search_{name}")
# Check for "no results" indicator
no_results = (
"no match" in content.lower()
or "no entities found" in content.lower()
or "no records" in content.lower()
or "0 results" in content.lower()
)
if no_results:
return NameSearchResult(
available=True,
exact_match=False,
similar_names=[],
state_code="TX",
searched_name=name,
raw_response=content[:2000],
)
# Extract matching entity names from results
similar: list[str] = []
# Common patterns: table rows with entity names
name_pattern = re.compile(
r'<td[^>]*>([^<]*?' + re.escape(name[:10]) + r'[^<]*?)</td>',
re.IGNORECASE,
)
for m in name_pattern.finditer(content):
found = m.group(1).strip()
if found and len(found) > 3:
similar.append(found)
# Exact match = one of the results matches our name closely
exact = any(
s.upper().replace(",", "").replace(".", "").strip()
== name.upper().replace(",", "").replace(".", "").strip()
for s in similar
)
return NameSearchResult(
available=not exact,
exact_match=exact,
similar_names=similar[:10],
state_code="TX",
searched_name=name,
raw_response=content[:2000],
)
except Exception as exc:
return NameSearchResult(
available=False,
state_code="TX",
searched_name=name,
raw_response=f"Error: {exc}",
)
# ── LLC Filing (SOSDirect — requires login) ─────────────────────────
async def file_llc(self, order: FormationOrder) -> FilingResult:
"""File a Certificate of Formation for a Texas LLC via SOSDirect.
SOSDirect flow:
1. Login with SOS account credentials
2. Navigate: Corporations File a Document Certificate of Formation
3. Select entity type: Domestic Limited Liability Company (Form 205)
4. Fill form fields (name, RA, members, management type, purpose)
5. Pay $300 ($325 for 24hr expedited, $350 for same-day)
6. Capture confirmation + filing number
Selectors need verification against live portal. The form is a
multi-step ASP.NET WebForms wizard.
"""
# TODO: Verify selectors against live SOSDirect portal session
# For now, return a stub that creates an admin todo for manual filing
return FilingResult(
success=False,
status=FilingStatus.PENDING,
state_code="TX",
entity_name=order.entity_name,
error_message=(
"TX SOSDirect adapter selectors pending verification. "
"Admin: file manually at https://direct.sos.state.tx.us "
f"— LLC Certificate of Formation (Form 205), ${CONFIG['fees']['llc']}."
),
)
# ── Corporation Filing ───────────────────────────────────────────────
async def file_corporation(self, order: FormationOrder) -> FilingResult:
"""File a Certificate of Formation for a Texas corporation.
Same SOSDirect flow as LLC but selects:
Domestic For-Profit Corporation (Form 201) or
Domestic Nonprofit Corporation (Form 202).
"""
return FilingResult(
success=False,
status=FilingStatus.PENDING,
state_code="TX",
entity_name=order.entity_name,
error_message=(
"TX SOSDirect adapter selectors pending verification. "
"Admin: file manually at https://direct.sos.state.tx.us "
f"— Corp Certificate of Formation, ${CONFIG['fees']['corporation']}."
),
)
def adapter() -> TXPortal:
return TXPortal()

View file

@ -0,0 +1,75 @@
"""Texas Secretary of State — SOSDirect portal configuration."""
CONFIG = {
"state": "Texas",
"abbreviation": "TX",
"agency": "Secretary of State",
"agency_url": "https://sos.state.tx.us",
"portal_name": "SOSDirect",
"portal_url": "https://direct.sos.state.tx.us",
"portal_login_required": True,
# Name search — Comptroller Taxable Entity Search (free, no login)
"name_search_url": "https://mycpa.cpa.state.tx.us/coa/Index.html",
# Alternative: SOSDirect name availability (requires login)
"name_search_url_alt": "https://direct.sos.state.tx.us",
# Filing status check
"filing_status_url": "https://webservices.sos.state.tx.us/filing-status/status.aspx",
# NW Registered Agent
"registered_agent": {
"name": "Northwest Registered Agent",
"street": "5900 Balcones Dr Ste 100",
"city": "Austin",
"state": "TX",
"zip": "78731",
},
# Fees (in USD, not cents — state portal charges in dollars)
"fees": {
"llc": 300,
"corporation": 300,
"nonprofit": 25,
"lp": 750,
"expedited_24hr": 25, # add-on for 24-hour processing
"expedited_same_day": 50, # add-on for same-day
"name_reservation": 40,
"name_reservation_days": 120,
},
# Selectors — verified against live portal on YYYY-MM-DD
# TODO: Verify during first live filing session
"selectors": {
# Comptroller name search page
"search_input": 'input[name="entityName"], input#entityName',
"search_button": 'input[type="submit"], #searchButton',
"results_table": "table.resultsTable, table#searchResults, table",
"no_results": ".noResults, .noMatch",
# SOSDirect login
"login_username": 'input[name="username"], input#txtUserName',
"login_password": 'input[name="password"], input#txtPassword',
"login_submit": 'input[type="submit"], #btnLogin',
# SOSDirect filing form (Form 205 - LLC)
"entity_name": 'input[name="entityName"], #txtEntityName',
"ra_name": 'input[name="agentName"], #txtAgentName',
"ra_street": 'input[name="agentStreet"], #txtAgentStreet',
"ra_city": 'input[name="agentCity"], #txtAgentCity',
"ra_state": 'select[name="agentState"], #ddlAgentState',
"ra_zip": 'input[name="agentZip"], #txtAgentZip',
"purpose": 'textarea[name="purpose"], #txtPurpose',
"management_type_member": 'input[value="member"], #rbMemberManaged',
"management_type_manager": 'input[value="manager"], #rbManagerManaged',
"member_name": 'input[name="memberName"], #txtMemberName',
"member_address": 'input[name="memberAddress"], #txtMemberAddress',
},
"notes": (
"Texas uses 'Certificate of Formation' (not Articles). "
"Franchise tax applies only to revenue > $2.47M (most small carriers exempt). "
"SOSDirect requires account creation (free). "
"No publication requirement."
),
}