# Project Context

When working with this codebase, prioritize readability over cleverness. Ask clarifying questions before making architectural changes.

## About This Project

Museu.io Companion is a WordPress plugin at ~/www/tema/wp-content/plugins/museuio-companion, which is shared by my classic theme (~/www/tema/wp-content/themes/museuio-theme) and my FSE theme (~/www/tema-fse/wp-content/themes/museuio-theme). I also have a corresponding child theme for each theme.

It adds a lot of funcionality to the themes, including many Block Eitor blocks, a Custom Fields system, integration with the Tainacan Plugin, and many extensions to core blocks, especially the Query Loop block, to enable advanced filtering of dynamic content.

## Key Directories

- **build/**: Never edit directly. Always edit in `src/` then run `npm run build` to compile.
- **src/**: Source files for blocks, variations, extensions, and components
  - `src/variations/query/enhanced-query/`: Query Loop extensions and filtering system
  - `src/extensions/custom-fields/`: Custom Fields system including Record field

## Build Process

Run `npm run build` after any changes to `src/` directory. The build uses `@wordpress/scripts` with `--webpack-copy-php` flag to copy PHP files from `src/` to `build/`.

## Logging Strategy

Create log files in the plugin root or `wp-content/` directory (e.g., `/Users/bf/www/tema/wp-content/debug.log`) since system/WordPress log locations vary across dev environments. Always delete log files when debugging is complete.

Use `file_put_contents($logPath, $message, FILE_APPEND)` instead of `error_log()` for consistent logging.

## Custom Fields System

### Record Field Architecture

The Record field is a repeating field type that stores arrays of subfield references:

- **Main field** (e.g., `mio_event_participants_record`): Stores array of record entries, each containing subfield meta_ids
- **Subfields** (e.g., `mio_event_participants_record_person_teste_record`): Stored as separate postmeta entries
- **Meta ID references**: Record entries store meta_ids, not actual values. Use direct database queries to retrieve values:
  ```php
  global $wpdb;
  $value = $wpdb->get_var($wpdb->prepare(
      "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_id = %d",
      $metaId
  ));
  ```
- **Notation**: Subfields use colon notation: `recordFieldKey:subfieldKey`

### Record Field Limitations

- Frontend doesn't have `__umeta_ids` (only available in REST API)
- Must query database by meta_id to get actual values
- Record entry structure:
  ```php
  [
      ['_id' => 'record_xxx', 'subfield1' => 11981, 'subfield2' => 11983],
      ['_id' => 'record_yyy', 'subfield1' => 11980, 'subfield2' => 11982]
  ]
  ```

## Query Loop Filtering System

### Record Meta Filters

Located in: `src/variations/query/enhanced-query/features/record-meta/`

- **mio-record-meta-filters.php**: Filter application logic
- **Grouping**: Filters are grouped by record key before processing
- **Direction modes**:
  - `direct`: Find posts that have current post in their records (uses LIKE query)
  - `reverse`: Find posts whose IDs are in current post's records (uses post__in)
- **Multi-condition logic**: When any filter on a record has direction, ALL filters on that record are evaluated together against the source post's metadata

### Filter Processing Flow

1. Parse `recordSubfieldKey` notation (e.g., `mio_event_participants_record:person_teste_record`)
2. Group filters by record key
3. Detect if any filter has direction
4. **If directional**: Evaluate all conditions on source post's records, extract matching IDs
5. **If non-directional**: Build meta_query + post-process results to ensure all conditions match within same record entry

