### Install Dependencies and Configure Environment Source: https://github.com/geobrowser/geogenesis/blob/master/CONTRIBUTING.md Installs project dependencies using Bun, navigates to the web application directory, and copies the environment example file to create a local configuration. ```bash bun install cd apps/web cp .env.example .env.local # fill in the .env.local file with the correct values ``` -------------------------------- ### Run Frontend Development Server Source: https://github.com/geobrowser/geogenesis/blob/master/CONTRIBUTING.md Navigates to the web application directory and starts the development server using Bun. ```bash cd apps/web bun dev ``` -------------------------------- ### Run Development Server Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/README.md Starts the development server for Geobrowser. Use this for active development and testing. ```sh # Run dev bun dev ``` -------------------------------- ### Example Action Data Encoding Source: https://github.com/geobrowser/geogenesis/blob/master/docs/brainstorms/2026-02-02-member-management-hooks-brainstorm.md Illustrates how to encode the data for a specific action, such as adding a member, using `abi.encodeCall` with the target function signature. ```solidity bytes data; // abi.encodeCall(IDAOSpace.addMember, (targetSpaceId)) ``` -------------------------------- ### TanStack DB RelationsCollection Setup Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/PROPOSAL-tanstack-db.md Sets up 'relationsCollection' using TanStack DB's queryCollectionOptions with 'on-demand' sync. It mirrors the valuesCollection setup but focuses on relation data, including schema, key extraction, and query function. ```typescript export const relationsCollection = createCollection( queryCollectionOptions({ id: 'relations', schema: relationSchema, getKey: relation => relation.id, syncMode: 'on-demand', queryKey: ['relations'], queryFn: async ctx => { const predicates = ctx.meta?.loadSubsetOptions; const where = tanstackPredicatesToWhereCondition(predicates); const filter = convertWhereConditionToEntityFilter(where); const entities = await getAllEntities({ filter }); return entities.flatMap(e => e.relations); }, }) ); ``` -------------------------------- ### TanStack DB QueryCollection Setup Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/PROPOSAL-tanstack-db.md Sets up 'valuesCollection' using TanStack DB's queryCollectionOptions with 'on-demand' sync. It includes schema, key extraction, query key, and a query function that translates TanStack predicates to API filters. ```typescript import { queryCollectionOptions } from '@tanstack/query-db-collection'; import { createCollection } from '@tanstack/react-db'; export const valuesCollection = createCollection( queryCollectionOptions({ id: 'values', schema: valueSchema, getKey: value => value.id, syncMode: 'on-demand', queryKey: ['values'], queryFn: async ctx => { // TanStack passes predicates from useLiveQuery const predicates = ctx.meta?.loadSubsetOptions; // Translate: TanStack predicates → WhereCondition → GraphQL const where = tanstackPredicatesToWhereCondition(predicates); const filter = convertWhereConditionToEntityFilter(where); const entities = await getAllEntities({ filter }); return entities.flatMap(e => e.values); }, onUpdate: async ({ transaction }) => { // Handle optimistic updates - called when value is mutated // Could be no-op if we batch publish separately }, }) ); ``` -------------------------------- ### useQueryEntities sortBy Example Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/AUDIT.md This snippet shows the sortBy configuration within the useQueryEntities hook. Note that the sortBy functionality is hardcoded but not fully implemented in the applySorting function. ```tsx .sortBy({ field: 'updatedAt', direction: 'desc' }) ``` -------------------------------- ### PostgreSQL Optimal Active Connections Formula Source: https://github.com/geobrowser/geogenesis/blob/master/docs/research/2026-02-04-topic-synthesis-postgres-connection-pooling.md This formula provides a starting point for determining the optimal number of active connections based on hardware factors. It's crucial to consider that 'effective_spindle_count' can vary based on cache hit rates. ```text Optimal active connections = (core_count * 2) + effective_spindle_count ``` -------------------------------- ### TanStack DB Collections Setup Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/PROPOSAL-tanstack-db.md Defines TanStack DB collections for 'values' and 'relations' using `localOnlyCollectionOptions`. Ensure `valueSchema` and `relationSchema` are defined elsewhere. ```typescript import { localOnlyCollectionOptions } from '@tanstack/db'; import { createCollection } from '@tanstack/react-db'; export const valuesCollection = createCollection( localOnlyCollectionOptions({ id: 'values', schema: valueSchema, getKey: value => value.id, }) ); export const relationsCollection = createCollection( localOnlyCollectionOptions({ id: 'relations', schema: relationSchema, getKey: relation => relation.id, }) ); ``` -------------------------------- ### Global Singleton Initialization Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/AUDIT.md Demonstrates the initialization of module-level singletons for the event stream, store, and sync engine. These singletons persist across route navigations. ```tsx export const stream = new GeoEventStream(); export const store = new GeoStore(stream); export const engine = new SyncEngine(stream, queryClient, store); ``` -------------------------------- ### Build Web Application Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/README.md Compiles the Geobrowser web application for deployment. This command generates optimized production assets. ```sh # Build web app bun build ``` -------------------------------- ### SpaceRegistry.enter() Function Signature Source: https://github.com/geobrowser/geogenesis/blob/master/docs/brainstorms/2026-02-02-member-management-hooks-brainstorm.md The `enter` function in `SpaceRegistry` is the entry point for all membership management actions. It accepts parameters for the caller's space, the target DAO space, the action type, topic, encoded data, and signature. ```solidity function enter( bytes16 _fromSpaceId, // Caller's personal space ID bytes16 _toSpaceId, // Target DAO space ID bytes32 _action, // PROPOSAL_CREATED bytes32 _topic, // bytes32(0) - fetch() returns proposalId bytes calldata _data, // Encoded proposal data bytes calldata _signature // Empty if caller owns fromSpace ) ``` -------------------------------- ### Verify Refactoring with Build Commands Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-02-refactor-flatten-v2-directory-structure-plan.md Run TypeScript compilation, tests, and build commands to ensure the refactoring changes have been applied correctly and the project remains functional. ```bash # TypeScript compilation pnpm tsc --noEmit # Run tests pnpm test # Build pnpm build ``` -------------------------------- ### Run Production Web App Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/README.md Builds and then runs the production version of the Geobrowser web application. This is typically used after the build step for deployment. ```sh # Run production version of web app bun build bun start ``` -------------------------------- ### Proposed File Structure Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-04-feat-voting-on-proposals-plan.md Illustrates the directory structure for new and modified files related to the voting feature. ```bash core/ ├── contracts/ │ └── voting.ts # NEW: Calldata encoding abstraction ├── hooks/ │ ├── use-vote.ts # MODIFY: Add validation, error handling │ └── use-proposal.ts # NEW: Merge server data with optimistic state ├── utils/ │ ├── contract-errors.ts # NEW: Contract error parsing │ └── transaction-errors.ts # NEW: Transaction classification └── state/ └── status-bar-store.tsx # MODIFY: Enhanced transaction states partials/ └── governance/ ├── proposal-vote-actions.tsx # NEW: Voting UI component └── governance-proposals-list.tsx # MODIFY: Add vote actions ``` -------------------------------- ### Data Encoding for PROPOSAL_CREATED Action Source: https://github.com/geobrowser/geogenesis/blob/master/docs/brainstorms/2026-02-02-member-management-hooks-brainstorm.md This structure shows how to encode proposal data for the `PROPOSAL_CREATED` action. It includes the proposal ID, voting mode, and an array of actions, where each action specifies the target address, value, and encoded data. ```solidity abi.encode( proposalId, // bytes16 - generated by hook votingMode, // VotingMode enum (Fast = 0, Slow = 1) actions // Action[] - array of {to, value, data} ) ``` -------------------------------- ### File Renaming and Relocation for v2 Flattening Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-02-refactor-flatten-v2-directory-structure-plan.md This snippet details the proposed file renames and relocations as part of flattening the 'io/v2/' directory. It outlines the target locations for files currently in 'io/v2/'. ```text io/v2/v2.schema.ts → io/schema.ts (rename legacy to substream-schema.ts first) OR → io/api-schema.ts (if keeping legacy schema.ts) io/v2/graphql.ts → io/graphql-client.ts (avoid conflict with subgraph/graphql.ts) io/v2/fragments.tsx → io/query-fragments.tsx (avoid conflict, clarify purpose) io/v2/queries.ts → io/queries.ts io/v2/converters.ts → io/converters.ts io/v2/converters.test.ts → io/converters.test.ts io/v2/decoders/ → io/decoders/ ``` -------------------------------- ### Abstract Contract Encoding Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-04-feat-voting-on-proposals-plan.md Create a domain service to abstract ABI encoding details from the voting hook. ```typescript // core/contracts/voting.ts import { MainVotingAbi, VoteOption } from '@geoprotocol/geo-sdk/abis' import { encodeFunctionData } from 'viem' export type VoteChoice = 'ACCEPT' | 'REJECT' export const VotingContract = { encodeVote(proposalId: string, choice: VoteChoice): `0x${string}` { return encodeFunctionData({ abi: MainVotingAbi, functionName: 'vote', args: [ BigInt(proposalId), choice === 'ACCEPT' ? VoteOption.Yes : VoteOption.No, true, // tryEarlyExecution ], }) }, encodeExecute(proposalId: string): `0x${string}` { return encodeFunctionData({ abi: MainVotingAbi, functionName: 'execute', args: [BigInt(proposalId)], }) }, } ``` -------------------------------- ### Import New Member Hooks Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-02-member-management-hooks-plan.md Replace existing member management hooks with new ones that support proposing member additions and removals. ```typescript // Remove: import { useAddMember } from '../../core/hooks/use-add-member' import { useRemoveMember } from '../../core/hooks/use-remove-member' // Add: import { useProposeAddMember } from '../../core/hooks/use-propose-add-member' import { useProposeRemoveMember } from '../../core/hooks/use-propose-remove-member' ``` -------------------------------- ### Import New Editor Hooks Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-02-member-management-hooks-plan.md Replace existing editor management hooks with new ones that support proposing editor additions and removals. ```typescript // Remove: import { useAddEditor } from '../../core/hooks/use-add-editor' import { useRemoveEditor } from '../../core/hooks/use-remove-editor' // Add: import { useProposeAddEditor } from '../../core/hooks/use-propose-add-editor' import { useProposeRemoveEditor } from '../../core/hooks/use-propose-remove-editor' ``` -------------------------------- ### Rename and Move Schema Files Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-02-refactor-flatten-v2-directory-structure-plan.md Execute git commands to rename the legacy schema file and move V2 schema-related files to their new locations. This includes renaming the main schema file and relocating its associated graphql, fragments, queries, converters, and decoders. ```bash # Create backup branch git checkout -b refactor/flatten-v2-backup # Rename legacy schema first git mv apps/web/core/io/schema.ts apps/web/core/io/substream-schema.ts # Move v2 files git mv apps/web/core/io/v2/v2.schema.ts apps/web/core/io/schema.ts git mv apps/web/core/io/v2/graphql.ts apps/web/core/io/graphql-client.ts git mv apps/web/core/io/v2/fragments.tsx apps/web/core/io/query-fragments.tsx git mv apps/web/core/io/v2/queries.ts apps/web/core/io/queries.ts git mv apps/web/core/io/v2/converters.ts apps/web/core/io/converters.ts git mv apps/web/core/io/v2/converters.test.ts apps/web/core/io/converters.test.ts git mv apps/web/core/io/v2/decoders apps/web/core/io/decoders # Remove empty v2 directory rmdir apps/web/core/io/v2 ``` -------------------------------- ### Audit io/schema.ts Usages Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-02-refactor-flatten-v2-directory-structure-plan.md Use grep to find all occurrences of 'from "~/core/io/schema"' in TypeScript and TSX files within the apps/web directory. ```bash # Check all usages grep -r "from '~/core/io/schema" apps/web --include="*.ts" --include="*.tsx" ``` -------------------------------- ### Update List Item Name and Description Edits Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-11-fix-data-block-cell-writes-plan.md Shows how to update `onChangeEntry` calls for name and description edits in list items, aligning with the new action types for SET_NAME, SET_VALUE, FIND_ENTITY, and CREATE_ENTITY. ```typescript // Name edits → { type: 'SET_NAME', name: value } // Description edit → { type: 'SET_VALUE', property: descriptionProperty, value } // FOC Find/Create → { type: 'FIND_ENTITY', entity } / { type: 'CREATE_ENTITY', name } ``` -------------------------------- ### Add keepPreviousData to useQuery for Schema Transitions Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-10-fix-new-entity-default-properties-plan.md By adding `placeholderData: keepPreviousData` to the `useQuery` options, this prevents the schema from briefly becoming undefined when the query key changes, such as during type additions or removals. This option is already imported but was previously unused. ```typescript const { data: schema } = useQuery({ enabled: types.length > 0, placeholderData: keepPreviousData, queryKey: ['entity-schema-for-merging', entityId, types], queryFn: async () => await getSchemaFromTypeIds(types.map((t) => t.id)), }) ``` -------------------------------- ### Current Reactivity with useSelector Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/AUDIT.md This snippet illustrates the current global reactivity model where any change to values triggers all useSelector subscribers. This can lead to numerous selector runs and potential re-renders even if the data hasn't changed significantly for a specific component. ```typescript const reactive = createAtom(() => ({ values: reactiveValues.get(), relations: reactiveRelations.get(), })); ``` -------------------------------- ### PgBouncer Connection Limits Configuration Source: https://github.com/geobrowser/geogenesis/blob/master/docs/research/2026-02-04-topic-synthesis-postgres-connection-pooling.md Defines the maximum number of client connections and server connection pools for PgBouncer. 'max_client_conn' limits incoming connections, while 'default_pool_size' sets server connections per user/database pair. 'max_db_connections' and 'max_user_connections' can be set to 0 for unlimited server connections per database or user, respectively. ```ini max_client_conn = 100 default_pool_size = 20 max_db_connections = 0 max_user_connections = 0 ``` -------------------------------- ### Proposal Created Action Constant Source: https://github.com/geobrowser/geogenesis/blob/master/docs/brainstorms/2026-02-02-member-management-hooks-brainstorm.md Defines the keccak256 hash for the `PROPOSAL_CREATED` action type. This constant is used in the `SpaceRegistry.enter()` function to identify the type of governance action being performed. ```typescript const PROPOSAL_CREATED = keccak256('GOVERNANCE.PROPOSAL_CREATED') // = 0x... (compute at implementation time) ``` -------------------------------- ### Sync Engine Integration with TanStack DB Collections Source: https://github.com/geobrowser/geogenesis/blob/master/apps/web/core/sync/PROPOSAL-tanstack-db.md Populates TanStack DB collections ('valuesCollection', 'relationsCollection') from fetched entities. Local changes take precedence over synced data. ```typescript // SyncEngine populates collections after fetch private syncEntities(entities: Entity[]) { for (const entity of entities) { for (const value of entity.values) { const existing = valuesCollection.get(value.id) if (existing?.isLocal) continue // Local wins valuesCollection.insert(value) } for (const relation of entity.relations) { const existing = relationsCollection.get(relation.id) if (existing?.isLocal) continue relationsCollection.insert(relation) } } } ``` -------------------------------- ### Handle Indexer Sync Gap with Polling Source: https://github.com/geobrowser/geogenesis/blob/master/docs/plans/2026-02-04-feat-voting-on-proposals-plan.md Implement polling with staged optimistic updates to handle indexer sync gaps after transaction confirmation. ```typescript onSuccess: async ({ hash, choice }) => { // Keep showing "confirming" state while polling // Poll for indexer to catch up (with timeout) const synced = await pollForIndexerSync({ proposalId: onchainProposalId, expectedVote: choice, maxAttempts: 10, intervalMs: 2000, }); // Only invalidate after indexer has synced queryClient.invalidateQueries({ queryKey: ['proposal', onchainProposalId] }); queryClient.invalidateQueries({ queryKey: ['proposals', spaceId] }); }, ``` -------------------------------- ### Add w-full to Property Wrapper Div Source: https://github.com/geobrowser/geogenesis/blob/master/docs/solutions/handoffs/format-card-width-20260210.md Ensures each property item takes the full width of the properties list container. This change is applied to the root div of a property item. ```tsx