# Politigraph > Politigraph is a public GraphQL API of Thai political open data - politicians, political parties, parliamentary positions, votes and bills - stored as a graph and maintained by WeVis. Query it by sending a POST request to https://politigraph.wevis.info/graphql. If you cannot run the query yourself, hand the user a link to https://politigraph.wevis.info/playground?query=URL_ENCODED_GRAPHQL&variables=URL_ENCODED_JSON instead. It opens the playground with that operation and its variables filled in, ready to run. This file contains the complete English documentation followed by the full GraphQL schema. # Introduction The [WeVis](https://wevis.info) team has been working with data related to Thai politics for many years. We found that Thai open data is scattered, lacks standardized collection sources, and is often in difficult-to-use formats such as PDFs. Therefore, we created **"Politigraph"** to elevate the standards of Open Data and Open API in Thailand. > **Caution: We cannot be held responsible for any errors or consequences arising from the use of this data.** > > We are not a government agency that directly owns and is responsible for publishing this data. > If you have any suggestions or feedback, please email team@wevis.info > or create a new issue on the project's [GitHub](https://github.com/wevisdemo/politigraph). ## System Structure We use an [Automation System](https://github.com/wevisdemo/politigraph-automation) to collect data from various official government sources, convert it into a machine-readable format, and have a team constantly reviewing its accuracy. ```mermaid graph TD A[Official Government Websites] -->|Pull and Convert Data| B[Automation System] B -->|Update| C[Politigraph] D[WeVis Data Team] -->|Add, Review, Correct| C C -->|Query| E[Parliament Watch] C -->|Query| F[Other Projects] C -->|Query| G[Interested Users] ``` We intend to open Politigraph as a public database, allowing users and various projects to utilize the data. We believe that effective open data fosters innovation, supports civic participation, and builds a strong democratic society. > **Tip: For general users interested in the work of the Thai Parliament** > > We recommend using [Parliament Watch](https://parliamentwatch.wevis.info), > a website that displays data from Politigraph in an easy-to-understand format. ## Data in Graph Format Politigraph store the data in the **"Graph"** structure which consists of 1. **"Node"** representing each entity in the database (has circle symbol). Each node have they own data called **"property"** such as a node representing person might have properties of first name, last name, birthdate, etc. 2. **"Relationship"** or sometimes called edge (has arrow symbol) representing a relationship between two nodes. ```mermaid graph TD A((Node A)) -->|Relationship| B((Node B)) ``` Due to the large number of nodes and relationships in Politigraph, we need to extract data for each point of interest. We call the code writing process to select nodes and relationships of interest **"query"** and the returned data **"response"**, which is in JSON format: machine-readable and convenient for further use. However, to make it easier to visualize, we will visualize the response in this documentation in the form of a graph. For example, if we want to know _"Which vote event did Anutin Charnvirakul were agreeing with?"_ We can query a node representing him and the relationships that lead to the votes he were agreeing and the vote event. ```graphql query People($where: PersonWhere, $votesWhere2: VoteWhere) { people(where: $where) { id name name_en image votes(where: $votesWhere2) { id option_en vote_events { id title nickname result start_date end_date } } } } ``` Variables: ```json { "where": { "firstname_en": { "eq": "Anutin" }, "lastname_en": { "eq": "Charnvirakul" } }, "votesWhere2": { "option": { "eq": "เห็นด้วย" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAAoIQAOANggBQAkA7gBb4Lqn4DOESA6qzwIANEXoA3CCgRcBbAEwcAalIRyhASiLAAOkiJEK5anRZsOTQQi279BogEswe+0SQBDRC-sfEAfWRvAwc4dwBzBCCiSWkuWjMhCxiZdQR5Gyjg5ztXShQHXgCkTOjVAPFkFC5tEqzaonyUGnqkBygAa19InNciIS4YKhR6rhR3PBQ-MHdpeuQwKZnu3qIAXyj1u03VkGEQcXGHdwAjGi4MEFsDHRAEyIwanpuAMwc8Ua6im44r3puELDfIg3ACCSBg+WKIA2wiiNyo7g+ngQXwev1c-0BDxuAGFmOMkOI3u52oMbhtvKtYXYbslZFZ5ED0cCQHkClCfiVMUCboABOEA1HCAcThAJhwgBQ4QCScIByOEARHDknqbAzbECrIA) You can also visit [Explore](https://politigraph.wevis.info/en/explore) to browse the data in Politigraph without writing any code. --- # Usage Our API adheres to the [GraphQL](https://graphql.org) standard, which you can query at `https://politigraph.wevis.info/graphql` through a [GraphQL Client or HTTP Request](https://www.graphql-js.org/docs/graphql-clients/) We also provide - [GraphQL Playground](https://politigraph.wevis.info/graphql) to try building various queries and explore the results - [Explore](https://politigraph.wevis.info/en/explore) the data through interactive visualization ## Using with AI Agents We provide two interfaces for AI coding agent or chatbot. > **Caution: AI responses can be inaccurate or misleading** > > An AI agent may build a query that does not answer your question, misinterpret the schema, or state figures that never came from Politigraph at all. > Before relying on or publishing an answer, you should verify the result yourself, for example by re-running it in the [GraphQL Playground](https://politigraph.wevis.info/graphql). ### llms.txt Our documentation are published as machine-readable plain text following the [llms.txt](https://llmstxt.org) convention: - [`/llms.txt`](https://politigraph.wevis.info/llms.txt): an index of every documentation page and resource, with links - [`/llms-full.txt`](https://politigraph.wevis.info/llms-full.txt): the entire documentation plus the full GraphQL schema in a single file - [`/schema.graphql`](https://politigraph.wevis.info/schema.graphql): the complete GraphQL schema (SDL) Give your agent `https://politigraph.wevis.info/llms.txt` to let it pick what it needs, or `https://politigraph.wevis.info/llms-full.txt` to hand it everything at once. **Example prompt** ``` Understand Politigraph via https://politigraph.wevis.info/llms.txt, then find which representative was absent from the most vote events in the current representative term. Break down the query you sent and the result you got from Politigraph. ``` ### MCP Server If your agent speaks the [Model Context Protocol](https://modelcontextprotocol.io), connect it to our MCP endpoint at `https://politigraph.wevis.info/mcp` instead. No authentication or API key is required. **MCP client configuration** ``` { "type": "http", "url": "https://politigraph.wevis.info/mcp" } ``` ### Client Compatibility An agent on your machine can read our documentation and send the query itself, so it can answer with real data. A chatbot in the browser can only read the documentation and help you write a query, but you have to run it yourself in the [GraphQL Playground](https://politigraph.wevis.info/graphql). Connect the chatbot to our MCP server if you want it to return real data. #### Web chatbots | Provider | llms.txt | MCP server | | ---------------------------------------------------------------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------- | | [ChatGPT](https://platform.openai.com/docs/guides/developer-mode) | Reads it, drafts queries | Custom connector in developer mode, on paid plans | | [Claude](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp) | Reads it, drafts queries | Custom connector on every plan, web and desktop, one connector when on free | | [Gemini](https://support.google.com/g/answer/17106276) | Reads it, drafts queries | Custom app in Spark on AI Pro and Ultra, or through an admin on Business | | [Perplexity](https://www.perplexity.ai/help-center/en/articles/13915507-adding-custom-remote-connectors) | Reads it, drafts queries | Custom remote connector, on paid plans | | [Microsoft Copilot](https://learn.microsoft.com/en-us/microsoft-copilot-studio/mcp-add-existing-server-to-agent) | Reads it, drafts queries | Only through an agent you build in Copilot Studio | #### Local coding agents | Client | llms.txt | MCP server | | ------------------------------------------------------------------------------------------ | ----------------------------- | ------------------------------- | | [Claude Code](https://docs.claude.com/en/docs/claude-code/mcp) | Reads it and runs queries | Yes | | [Codex CLI](https://developers.openai.com/codex/agent-approvals-security) | Needs `network_access = true` | Yes | | [Gemini CLI](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html) | Reads it and runs queries | Yes, configured under `httpUrl` | | [Cursor](https://cursor.com/docs/context/mcp) | Reads it and runs queries | Yes | | [VS Code with GitHub Copilot](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) | Reads it and runs queries | Yes | _Last checked on 7 September 2026_ ## Limitations ### Access Most data from the Politigraph API is publicly accessible and does not require authentication, with the following exceptions: - Data with the field `publish_status` that does not have the value `PUBLISHED` will be hidden from the response because it is under review and not yet ready for disclosure. - Any GraphQL mutation, as we prevent external parties from modifying data on our system. Access to both of these exceptions is strictly reserved for the WeVis system administration team. ### API Usage Limits To ensure fair usage and protect the API from abuse, we enforce the following limits on GraphQL operations, both through GraphQL endpoint and MCP: - **Rate limit**: 30 requests per 10 seconds - **Batching**: 5 operations per batched request - **Aliases**: 120 aliases per operation - **Depth**: 10 levels of nested operation - **Tokens**: 10,000 tokens per operation Exceeding these limits will result in an error response. ### Node Limits Certain types of data, such as "People" and individual "Votes", contain a large number of nodes within the system. We must limit the number of nodes returned to the user to no more than 1,000 nodes per query. If you need to retrieve more data than this limit allows, please [read more about using Pagination on GraphQL](https://neo4j.com/docs/graphql/current/queries-aggregations/pagination/). ## License Regarding the data, the team intends to open it as Open Data under the [Attribution-NonCommercial 4.0 International](https://creativecommons.org/licenses/by-nc/4.0/) terms. This means you can use, modify, and build upon the data, but it cannot be used for commercial purposes or to seek profit from the work, and credit must be given to WeVis. Regarding the source code, the team intends to develop every project as Open Source under the [Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/) terms. This means you can use, modify, and build upon the work, but it cannot be used for commercial purposes or to seek profit from the work. You must provide notice and credit to the work's owner, and the resulting work must be under the same Creative Commons license conditions as the original. WeVis Ltd. and Punch Up Ltd. are joint licensors. --- # Overview To ensure the database is organized, standardized, and easy to understand, we have designed a **schema** to define how many types of nodes exist, what properties each type has, and how these nodes can be connected to create relationships. We designed the Politigraph schema based on [Popolo - International open government data specifications](https://www.popoloproject.com/) with adaptations for the context of Thailand. The **schema** consists of: 1. **Object**: Types of actual data nodes, specifying the properties present in each node type. 2. **Interface**: Basic requirements for objects to extend. 3. **Union**: Sets of possible types. 4. **Relationship**: Possible relationships between different node types. Feel free to select entities to read the descriptions. _The interactive schema diagram is not available in plain text. The complete GraphQL schema is at https://politigraph.wevis.info/schema.graphql_ ## Node For example, we have these people with first-name starting with _"Nat"_ represented with nodes type of **`Person`**. These nodes will only have property and relationship that satisfy **`Person`** **schema** (they don't need to have optional properties, so querying those will have value of _null_) ```graphql query People($where: PersonWhere) { people(where: $where) { id prefix name_en image birth_date educations previous_occupations } } ``` Variables: ```json { "where": { "firstname_en": { "startsWith": "Nat" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAAoIQAOANggBQAkA7gBb4Lqn4DOESA6qzwIAlEWAAdJESIVy1OizYcmgkWMnTpASzAbNFIQDMtADz3SkAQ0QB9ZOaJa4lgOYIHAIy14UzG2EsUdylNBDAYKECtXi4HAwQAN2iYLhtoWAoomL0AX0kckAAaEATLPC1LDxouDBAJEPEQRSFGjnrNIkbjPC4UK1t7DHUQjsbespQuPi1fVs6QADlAxoc8kLWCnKA) ## Relationship Relationship in **schema** will have a name with arrow direction for human interpretation such as `Post--IN--> Organization` meaning **`Post`** is "in" an **`Organization`** But in the query process, either nodes at the both end can be queried from each other. For example, **`Post`** has property `organizations` and **`Organization`** has property `posts` that refer to each other node of this relationship. ```graphql query Organizations($where: OrganizationWhere, $postsWhere2: PostWhere) { organizations(where: $where) { id name_en posts(where: $postsWhere2) { id label role organizations { id name } } } } ``` Variables: ```json { "where": { "id": { "eq": "คณะรัฐมนตรี-64" } }, "postsWhere2": { "role": { "eq": "นายกรัฐมนตรี" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAPJ4DmAhkgJYBelKNESAzgBQAkA7gBb4J0pCtXqNmSAOr88CADRFOABwisUraQIBMQgAqqUm2QEoiwADpIiRCCNoMmLDnwFCeMhKYtXrRGmEtfIiRKRAB9ZEDfFTVnDzcY9SMELS8ooP903wAbSgAjBGys6zwIbIRimzsxRzYzSutMnyDrEMRKgF8srp8ejpA5EAA3SjwafPLWDBBva3MQF1l5oVnfecyMeua1kAQsZaJ5wBA4QGQ4QAY4QGI4QEY4QAQ4QEI4QEw4QFQ4C8BWOABaADYAFnnuqI6cii80SGg8WgOqzmIFK5UhlXmewO8wegCY4QBEcIBAOGu92ebz+2x61j6IA6QA) --- # Organization An organization is a formal grouping of people formed to carry out certain activities together. In Politigraph, organizations are stored as nodes of type **`Organization`**. Since organizations can be of various types, we use the `classification` property to specify those types. ## Parliament, MPs, Senators, and Cabinet The Thai Parliament (รัฐสภาไทย) has a `classification` of _PARLIAMENT_ and will have child organizations in the `children` property with different `classification` values such as: - **House of Representatives** (สภาผู้แทนราษฎร): _HOUSE_OF_REPRESENTATIVE_ - **House of Senate** (วุฒิสภา): _HOUSE_OF_SENATE_ - **Cabinet** (คณะรัฐมนตรี): _CABINET_ ```graphql query Query($where: OrganizationWhere) { organizations(where: $where) { id name_en classification founding_date dissolution_date children { id name_en classification description founding_date dissolution_date } } } ``` Variables: ```json { "where": { "classification": { "eq": "PARLIAMENT" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAIq6EAUAJAO4AW+C6RA8ngOYCGSAlgF6cUPCEgDqDPAgCURYAB0kRIhA7d+g4UgDOFeo2a0J02QqVKeYU2aSdEAfWRWlUADactWngDMeUDSKciLwgYJDAeJHY7MEEEQPCPCBcYIRFo2MCoOh4XMElFeUUzc0si4pt7RzKzV3dPHz9UpEClMAQtKDweAAcmlqCQsIiomJQ46taeROSm9LHAgF8rJaQFkAAaEAA3Ti7OACMXdowQQqU5ED1JC+Yzswvaj29ff2aMEwmiC4QsG6+QAAKAEEAEoAGQAkkCALIAUQAcgAVC6LZYKNYLIA) ## Political Parties Political parties are also classified as **`Organization`** with a `classification` of _POLITICAL_PARTY_. Here are all the political parties we have in the database. ```graphql query Organizations($where: OrganizationWhere) { organizations(where: $where) { id name name_en color } } ``` Variables: ```json { "where": { "classification": { "eq": "POLITICAL_PARTY" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAPJ4DmAhkgJYBelKNESAzgBQAkA7gBb4J0pCtXqNmSAOr88CAJRFgAHSREiEEbQZMWHPgKE8Z8xSrVqaYM+aSVE1tbcQB9ZA6JQIAGw3WAvip+IAA0IABulHg0lABGXgisGCDKqkRKIPqy6UIp5mkgUF6UrKw0AGY0UOIs2aapeekIWLXpAAokADIAkgAqXQDCAIIdzq2DAEo9AJrp7gGp80F+QA) --- # Membership A person **`Person`** or an organization **`Organization`** can be a member (**`Member`** union) of any organization. ## People with positions in an organization The relationship between a person and an organization is described by nodes in the following order: - **`Person`** is a person. - **`Membership`** is membership information, such as the format or period. - **`Post`** is a position in that organization. - **`Organization`** is an organization. For example, if we want to know what positions _Chuan Leekpai_ has held in which organizations. ```graphql query People($where: PersonWhere) { people(where: $where) { id name_en memberships { id label start_date end_date posts { id label organizations { id name_en name classification } } } } } ``` Variables: ```json { "where": { "firstname_en": { "eq": "Chuan" } }, "lastname_en": { "eq": "Leekpai" } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAAoIQAOANggBQAkA7gBb4Lqn4DOESA6qzwIAlEWAAdJESIVy1OizYcmgkWMnTpASzAbNSAIaIA+sj3TEcAEbdmWil3VTN23c5dUDNquc1cUBngoxmAGKAi+0shgIWER7poUEP6OEgkuOpGant5Z0hB4AOYGSFoAXmFavKl5mpnpLkSGJmYNLs3xjY1QnlxcWgBmWlCVvLUAvlmTCdPS0+MgADQgAG6BWl40XBggadLiIIpCBxx7mgdDeP4dpkgnTl0HCFj3BwDCzDAlB76zROOLPQHXooG5mDAPc4gZ6vEAAGQQCAA1hQDFofs55iBxkA) Because the graph database connects all nodes, we can start a query from any node. For example, if we want to know who has ever held the position of _leader_ of the _Pheu Thai Party_, we can start the query from **`Post`**. ```graphql query Posts($where: PostWhere) { posts(where: $where) { id label role organizations { id name_en name } memberships { id start_date end_date members { ... on Person { id name_en } } } } } ``` Variables: ```json { "where": { "role": { "eq": "หัวหน้าพรรคการเมือง" } }, "organizations": { "some": { "id": { "eq": "พรรคเพื่อไทย" } } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAAoQDOK5AFACQDuAFvguqRSgOrN4ICURYAB0kRIgAcONJizYMe-QSLFiAlmGUqANgEMARgi2axeCFoTGiEPAHMdSVQC8dKVRCTklolWo3efSDqIAPrIlmKBiJYAvpaIcAZ45Iyq4p7C-irq4USUOngowWAuFpliyGBFJTnxiek5YgB0zVaiJPjk7l4+PUTZZT2RCKFIDUSxAxM+U+Mi0SAANCAAbvmq+ubkGCAZYkIgMrz7bLsq+6bmx909+whYV-uA1HCAjHCA5HCPgJhwgJJwgExwgHhwgGI4AGAEDhAIBwPwBgAE4QCEcIB2OEAtHCAcDh9jFNNEFpp9tY7A5nK53OQrqc9iBOlEMNcfPtshTiTcQHcHiBASDIX9YYAJOHhgBE4QDocIAiOBRk1R3gm82iQA) ## Government and Opposition parties We model "Government parties (พรรคฝ่ายรัฐบาล)" and "Opposition parties (พรรคฝ่ายค้าน)" as a **`Post`** in the cabinet organization. ```graphql query Organizations($where: OrganizationWhere, $postsWhere2: PostWhere) { organizations(where: $where) { id name_en posts(where: $postsWhere2) { id label role memberships { id start_date end_date members { ... on Organization { id name } } } } } } ``` Variables: ```json { "where": { "id": { "eq": "คณะรัฐมนตรี-63" } }, "postsWhere2": { "role": { "startsWith": "พรรคฝ่าย" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAPJ4DmAhkgJYBelKNESAzgBQAkA7gBb4J0pCtXqNmSAOr88CADRFOABwisUraQIBMQgAqqUm2QEoiwADpIiRCCNoMmLDnwFCeMhKYtXrRGmEtfIiRKRAB9ZEDfFTVnDzcY9SMELS8ooP903wAbSgAjBGys6zwIbIRiokQ4ArxWXholVjNK60yfIOs1SjwUMLBGCo7O5DB+wdaqhBr8Zu9OzoA6ZZsrMip7cRYW4YW2gN29kMRJ6wBfSYvDq6CboiuzkDkQADcemnzy1gwQeaJzEAuWQAoR-awAzIYHYLAEILAg-4gQAgcIBkOEADHCAYjhAIxwgAQ4QCEcIBMOEAqHAYwCscABaABsAGYAVk7mc5FEAYkNB4tAiwYjSuVOZUAd1ehoaCheAiAYA8OAxGKRgFw4QAScIAmOEARHB04YMyyPM5AA) --- # Voting We collect voting data from both the House of Representatives and the Senate using **`VoteEvent`** to represent voting events and **`Vote`** to represent the casting of votes by each **`Person`**. The voting options (property `option` in **`Vote`**) in parliamentary votes generally have 5 formats: 1. Agree (เห็นด้วย) 2. Disagree (ไม่เห็นด้วย) 3. Abstain (งดออกเสียง) 4. No Vote (ไม่ลงคะแนนเสียง) 5. Absent (ลา / ขาดลงมติ) For example, the draft Budget Act 2021 (Section 3) and the voting of the 20 sample participants. ```graphql query VoteEvents( $where: VoteEventWhere $limit: Int $votesWhere2: VoteWhere $votesLimit2: Int ) { voteEvents(where: $where, limit: $limit) { id title nickname publish_status start_date result votes(where: $votesWhere2, limit: $votesLimit2) { id option_en voters { id name name_en } } } } ``` Variables: ```json { "where": { "id": { "eq": "fd854f98-a9c0-4ef2-b007-58821da695dc" } }, "votesWhere2": { "voters": { "all": { "NOT": { "firstname_en": { "eq": null } } } } }, "votesLimit2": 20 } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAGoQoICiAbsigM4AUAOkkUQCQDuAFvgulLkqtVAHU+eBK3YcANgEs4ClIICSqGZ2rD6E-gCZBZCvqlaOOivQAySlUaIaUrAJRFgWqyLpNe-QW5JBAAaIkVlVU4IlXdPNnYiBTAtdhQVOWkE9iQFKABrJABDRFSiAAcYACNFeh4AfXoUIpQYejKmorwUerAWrMSiKXoYORdsom8-YMCpswQDMJioy107SIM4svZk7aIIcvSIJHrkPe88eg89nZSJweLS+8THhFOkPYBfMu+E38+QCEQNQugoijUEPQMCB4uxmCB-OYMNcJvDdsjYYMiPCEFh4YJ4QAzMAADgArAAWQkAThJAFoitSoAAGOkUhCEgx0qrM5kAdjpZJJJIMAEY+gA2alksBQeE-LSfEJaeFzYIGfEowaq4SXTWY7UgIpyOT6m7YkAAOQA8gAVM3PQ2EhSXFCvd4OrFei24zVIUamx2JX7eoghrHh9jhpUq4FrewoDXIgzM1gAz5AA) ## Data Updates and Publish Status The House of Representatives' votes are automatically retrieved from the [Parliament Secretariat Database and Records System](https://msbis.parliament.go.th) every week by the [automation system](https://github.com/wevisdemo/politigraph-automation). - The data is scraped, OCR'd, and checked for inconsistencies. If it passes verification, the vote will have a `publish_status` of _PUBLISHED_ and will be made publicly available. - However, if errors are found, the `publish_status` will be _ERROR_, and it will not be displayed to the public until the team fixes it and changes the status back to _PUBLISHED_. The Senate's votes are not yet publicly available online, so we will not be able to update the data consistently. --- # Bill We collect data on the legislative process and the status of bills submitted for parliamentary consideration, with **`Bill`** representing each draft law. Each bill is classified into 3 types (property `classification` in **`Bill`**) as follows: 1. `NORMAL_BILL` (Bill / Draft Act): General bills proposed by the Cabinet, Members of the House of Representatives (MPs), or eligible voters through a public petition. 2. `BUDGET_BILL` (Annual Appropriation Bill): Bills concerning the allocation of the national budget. 3. `EMERGENCY_DECREE` (Emergency Decree): Laws enacted by the King upon the advice and consent of the Cabinet, exercising constitutional power in cases of emergency. Examples of the three bill types: ```graphql query Bills( $limit_a: Int $where_a: BillWhere $limit_b: Int $where_b: BillWhere $limit_c: Int $where_c: BillWhere ) { normal_bills: bills(limit: $limit_a, where: $where_a) { id title classification } budget_bills: bills(limit: $limit_b, where: $where_b) { id title classification } emergency_decree: bills(limit: $limit_c, where: $where_c) { id title classification } } ``` Variables: ```json { "limit_a": 1, "where_a": { "classification": { "eq": "NORMAL_BILL" } }, "limit_b": 1, "where_b": { "classification": { "eq": "BUDGET_BILL" } }, "limit_c": 1, "where_c": { "classification": { "eq": "EMERGENCY_DECREE" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAEICWANhQM4AUAOkkUQCQVlxkoD6AhukQCSqRsxYB3ABb4EfAeSoB1aXgSjW7TjwBGA4SnUSVs3aUoVlMw5q7coekU1ZSZd+ecurGASiLB1SBB4cLwU3Nrm1AIRVHQ2KAJsHLa8ADRELqqJmbK8vv5OzGRg6swoXBRqhURQFLzU1GQAZmRQvOUQSOoAvuraMGAA5gg6kdGRtPGJ8eHpOdnG4fmlRMUr5SiVK7X1jS1tHV1OvU4IiHjDSFAE3GAIUKoI47GTyQkab3ZzxguuUMvVNbVDZbao7BrNVrtMidHqMbogVIgABuvDwZF42kq1AwIAKzHoIBmvEJAgAjKl1IScnxSX4VoTwXsoYc6fjmBzCQgsHTCQA5ADyACUALIAQQAMtwSIIJRLCSsTsxupSnISZto6RSqSAaZqMPTqoy6hD9tDYQb2RyiFyeQbCSQAKoAEQA4gBRAAq0tl8pAip6qoJRM+UC1QZtusWYctDJATMhBxhXVj1WD3N5IHdIvdQo9fIAwgBNbjO90FoXu90K6pKognBHdIA) ### Bill Proposers and Co-proposers The origin of each bill can be classified into four proposer types (property `creator_type` in **`Bill`**): 1. `POLITICIAN`: Members of the House of Representatives (MPs) 2. `ASSEMBLY`: The Cabinet 3. `PEOPLE`: Eligible voters 4. `UNKNOWN`: Used in cases where the proposer group is unknown Each bill links to detailed information about its proposers (property `creators` in **`Bill`**) based on the following conditions: - In cases where the bill is proposed by the _Cabinet_, it links to the _proposing Cabinet_ represented as an **`Organization`**. - In cases where the bill is proposed by _Members of the House of Representatives (MPs)_, it links to the _proposing MPs_ represented as a **`Person`**. Additionally, bills proposed by _MPs_ can have **co-proposers** (property `co_creators` in **`Bill`**), which link to the _co-proposing MPs_ represented as a **`Person`**. - In cases where the bill is proposed by _eligible voters_, there are **no links** to any specific proposer data. Example of a bill proposed by _Members of the House of Representatives (MPs)_ ```graphql query Bills($limit: Int, $where: BillWhere) { bills(limit: $limit, where: $where) { id title classification creator_type creators { ... on Person { id name_en } } co_creators { id name_en } } } ``` Variables: ```json { "limit": 1, "where": { "creator_type": { "eq": "POLITICIAN" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAEICWANhQM4AUAJBWXGSukQJKoA0R9A7gAt8CduSoB1YXgQBKIsAA6SIkQBGlGrSYs2fHa15CR7AdLkLlq1WTBXrKVhQT3VUCgENq1MgDMyUB6OEEiuRFAyQRB4APooBAAOLirWEQhReNSWKdZEAHQFRCFEAAr41MVKOblEtmG5SB6IMcj1RAC+YZ3VUBAxaRlZVTW1dtWqjc2t1d2q3e0g3CAAbh54ZB5qztQYIMNEiiAGKIfsAIzc9ofGMqfZuYcDKNFxiS4Y9zWHCFh3hyUAeQAMhwACocADCHAAggA5Q5dezzEDtIA) ### Legislative Process After each bill is proposed to Parliament, it enters the legislative process consisting of various sequential stages. These stages are stored as a list of events (property `events` in **`Bill`**). > **Note** > > For detailed information regarding the stages of the legislative process, you > can study more in the manual: > > [กระบวนการพิจารณาร่างกฎหมาย](https://parliamentwatch.wevis.info/legislative-process) Since each stage is represented by a specific event and requires different data points to be recorded, the system uses distinct Node types for each consideration stage as follows: 1. `BillVoteEvent`: Voting stage 2. `BillMergeEvent`: Bill merging stage (merging multiple drafts into a primary bill) 3. `BillRoyalAssentEvent`: Royal Assent stage (submission for Royal signature) 4. `BillEnactEvent`: Enactment stage (promulgation as law) 5. `BillRejectEvent`: Rejection stage (when a bill is dropped or fails) ##### Voting Stage (`BillVoteEvent`) The voting stage is an event that records the parliamentary consideration and voting process to determine whether a bill will be approved or passed. The system separates these processes into the two main chambers: the House of Representatives and the Senate. The consideration stages of each chamber are divided into three main readings (property `classification` in **`BillVoteEvent`**) as follows: 1. `MP_1`: House of Representatives - First Reading 2. `MP_2`: House of Representatives - Second Reading 3. `MP_3`: House of Representatives - Third Reading 4. `SENATE_1`: Senate - First Reading 5. `SENATE_2`: Senate - Second Reading 6. `SENATE_3`: Senate - Third Reading During each reading, there may be votes on various specific details. This data links to **`VoteEvent`**, which stores the scoring details and individual votes (property `vote_events` in **`BillVoteEvent`**). Example: The House of Representatives consideration of the Annual Appropriation Bill for Fiscal Year 2025 (Third Reading). ```graphql query BillVoteEvents($where: BillVoteEventWhere) { billVoteEvents(where: $where) { id title classification bills { id title classification } vote_events { id title classification result } } } ``` Variables: ```json { "where": { "id": { "eq": "b5813539-007a-47de-b09b-22f127e15aa8" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAEICWANhQGoQoICiAbsigM4AUAJAO4AW+BOlKUadRi1QB1AXgQBKIsAA6SIkQBGo2vWatO-QcN6yFS1evVkwFyyjIoKCW+qgUAhmzZkAZmSju9hBILpqibOZqllY2UdH2js5xlm6e3n4BQSHJAL6hTOIA+giS7JHRMaHqCU5VRKlevv6BZMF1cmwwFCiheVF9OSAANCBM7nhk7hpObBggKlHKIIZyS8IL0UvWa+UVSwhYO0saAKwAHACMAMwnVwCcALQADE8A7O4PACyvYAgPGk87hoHgAmEE+C4g14IC4ndzuM5LXq2AYgHJAA) ##### Bill Merging Stage (`BillMergeEvent`) The bill merging stage is an event that occurs when multiple bills with similar content or principles are proposed to Parliament. The chamber resolves to consider these bills concurrently and designates one specific draft as the **"Primary Bill"** to serve as the basis for consideration in subsequent readings. In terms of data structure, all **`Bill`** nodes within the same deliberation group link to the same **`BillMergeEvent`**, representing their common point of consideration. The **`BillMergeEvent`** stores the **ID** (`id`) of the bill that the chamber resolved to use as the primary draft for further consideration (property `main_bill_id` in **`BillMergeEvent`**). Example of a bill being designated as the Primary Bill by the House of Representatives: ```graphql query BillMergeEvents($where: BillMergeEventWhere) { billMergeEvents(where: $where) { id main_bill_id total_merged_bills bills { id title } } } ``` Variables: ```json { "where": { "id": { "eq": "f54b6def-9b4f-41d0-a6f3-72bdc7ae36af" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAEICWANhQLL4DmCAogG7IoDOAFACQDuAFvgTpSlGvSatUAdUF4EASiLAAOkiJEARmNp4GLNlwFCRfOYuVqNGsmCvW4AQzJIA+tqqvb9jSggpHCldEPQQwdzF2Hy1Iy3VrGzt4hJQyFAoEaIBfexykLJAAGhBmRzwyR00M9gwQVXiVEGN5RpF6hMbvDDiEjUaELFaiRoAzAFYAFk0ANjAEEYBaAE5NCcWJgEYwAAYFx2mRgGYFgHYAJk0wKBPHBEPpxxHG7Ny1AqygA) ##### Royal Assent Submission Stage (`BillRoyalAssentEvent`) The Royal Assent submission stage is the event occurring after Parliament has approved a bill. The Prime Minister then proceeds to submit the bill to the King for the Royal Signature before it is officially promulgated as law. The **`BillRoyalAssentEvent`** stores the record of the Royal Decision or the acceptance status of the bill (property `result` in **`BillRoyalAssentEvent`**). Example of the Royal Assent submission stage for the Alcoholic Beverage Control Bill: ```graphql query BillRoyalAssentEvents($where: BillRoyalAssentEventWhere) { billRoyalAssentEvents(where: $where) { id result bills { id title } } } ``` Variables: ```json { "where": { "id": { "eq": "0beac91b-e207-4476-acc7-09c91741caf9" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAEICWANhQEoQECGFAggM4vIoCiAbhywBQASAO4ALfAnSlKNOo1btUPDgHVxeBAEoiwADpIiRAEYzaDZmw7LUAsRKkj1WnfsOGyYV240sYFFF6GJlQsLgZu7p7hEShkKBQIgUQAvl6pSMkgADQg3PR4ZPRGCSwYIHrhuiB2GlVSFRFVHnVhEYZVCFgtVQAMRgj0UACcAIxGALQIAEw9AOzjACwLswBs44NQ8z1DwyOzCyNQ9ABmQ1VJ6YbpmclAA) ##### Bill Rejection Stage (`BillRejectEvent`) The Bill Rejection Stage is an event that records the termination of a bill's legislative process. This occurs when a bill fails to receive approval or when specific circumstances prevent the bill from proceeding through the legislative steps to completion. **`BillRejectEvent`** stores the reason or cause for the bill being dropped (property `reject_reason` in **`BillRejectEvent`**). Common reasons include: the House of Representatives resolving not to accept the principles, the bill being withdrawn by the proposer, or the bill being dropped due to the dissolution of Parliament. Example of the rejection stage for the National Fisheries Fund Bill, which was dropped due to the dissolution of Parliament. ```graphql query BillRejectEvents($where: BillRejectEventWhere) { billRejectEvents(where: $where) { id reject_reason bills { id title } } } ``` Variables: ```json { "where": { "id": { "eq": "55fa6fde-3ed3-4b4e-9665-bccadc5646f2" } } } ``` [Run this query in the playground](https://politigraph.wevis.info/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAEICWANhQEoIBWCUKAogG7IoDOAFACQDuAC3wJ0pSjXqMW7VAHVheBAEoiwADpIiRAEYTaDJmw48hIsQMUq1m7drJhbdpYZQB9JQENOEJE+16VJw2Wnb2jqFhKGQoFAj+RAC+TslIiSAANCCsnnhknjpxnBggGqHqIGZKFWJlYRUONSFh2hUIWE0VAKxdAGaeAGy9YAgAtADMCGDjowAsOrNjAJwDA12jOlBQnmBQXQOzQwBMFQmp2qnpiUA) ### Current Status of a Bill Each bill displays a current status, which summarizes the latest event that has occurred in its legislative process (property `status` in **`Bill`**). There are 4 possible status types: 1. `IN_PROGRESS` (**In Progress**): Used for bills still undergoing parliamentary consideration (Readings 1-3) or in the process of being submitted for Royal Assent, where the deliberation is not yet complete or a final outcome has not been reached. 2. `MERGED` (**Merged**): Used for bills that the chamber has resolved to "merge" into another primary bill. Consequently, tracking for this specific draft ends, and further progress must be followed via the primary bill instead (see more details in **`BillMergeEvent`**). 3. `ENACTED` (**Enacted**): A positive final status, meaning the bill has received the Royal Signature and has been published in the Royal Gazette to be enforced as law (**`BillEnactEvent`**). 4. `REJECTED` (**Rejected / Dropped**): A negative final status, meaning the consideration process has ended because the bill was voted down, withdrawn, or dropped according to constitutional conditions (**`BillRejectEvent`**). ## Data Updates and Publish Status Data on bill proposals and the legislative process is scraped weekly from the [Legislative Information System](https://lis.parliament.go.th/index/index.php) website of the Secretariat of the House of Representatives by an [automation system](https://github.com/wevisdemo/politigraph-automation) and imported into the database. --- # GraphQL Schema ```graphql extend schema @authentication( operations: [ CREATE UPDATE DELETE CREATE_RELATIONSHIP DELETE_RELATIONSHIP ] ) type Query { """ เวลาที่ข้อมูลถูกเพิ่มหรือแก้ไขล่าสุด (UTC) """ lastUpdatedAt: DateTime } """ สถานะการเผยแพร่ """ enum PublishStatus { """ เผยแพร่สู่สาธารณะ """ PUBLISHED """ ไม่เผยแพร่สู่สาธารณะ """ UNPUBLISHED """ มีข้อผิดพลาด ต้องการการตรวจสอบ """ ERROR } """ ประเภทองค์กร """ enum OrganizationType { """ รัฐสภา """ PARLIAMENT """ สภาผู้แทนราษฎร (สส.) """ HOUSE_OF_REPRESENTATIVE """ วุฒิสภา (สว.) """ HOUSE_OF_SENATE """ คณะรัฐมนตรี (ครม.) """ CABINET """ พรรคการเมือง """ POLITICAL_PARTY """ หน่วยงานเอกชน """ PRIVATE_ORGANIZATION } """ สถานะของร่างกฏหมาย """ enum BillStatus { """ กำลังดำเนินการ """ IN_PROGRESS """ ถูกรวมร่าง """ MERGED """ ออกเป็นกฎหมาย """ ENACTED """ ตกไป """ REJECTED } """ ประเภทของผู้เสนอกฏหมาย """ enum BillCreatorType { """ สมาชิกรัฐสภา """ POLITICIAN """ คณะรัฐมนตรี """ ASSEMBLY """ ประชาชน """ PEOPLE """ อื่นๆ / ไม่พบข้อมูล """ UNKNOWN } """ เพศโดยกำเนิด """ enum Gender { """ ชาย """ MALE """ หญิง """ FEMALE } """ ประเภทของกฏหมาย """ enum BillType { # placeholder # TODO add & change enum """ ทั่วไป """ NORMAL_BILL """ เกี่ยวข้องกับงบประมาณ """ BUDGET_BILL """ ประกาศฉุกเฉิน """ EMERGENCY_DECREE } """ ประเภทของการลงมติ """ enum VoteEventType { """ สส. วาระที่ 1 """ MP_1 """ สส. วาระที่ 2 """ MP_2 """ สส. วาระที่ 3 """ MP_3 """ สว. วาระที่ 1 """ SENATE_1 """ สว. วาระที่ 2 """ SENATE_2 """ สว. วาระที่ 3 """ SENATE_3 """ การโหวตเลือกนายกรัฐมนตรี """ PM_VOTE } """ เหตุการที่เกี่ยวข้อง อ้างอิงจาก https://www.popoloproject.com/specs/event.html """ interface Event { """ ID แบบสุ่ม """ id: ID! """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @declareRelationship """ คำอธิบาย """ description: String """ วันที่เริ่ม """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @declareRelationship } """ ญัตติ อ้างอิงจาก https://www.popoloproject.com/specs/motion.html """ interface Motion { """ ID แบบสุ่ม """ id: ID! """ องค์กรที่พิจารณาญัตติ """ organizations: [Organization!]! @declareRelationship """ ผู้เสนอ """ creators: [MotionCreator!]! @declareRelationship """ ชื่อ """ title: String """ วันที่รับเรื่องในระบบ LIS """ proposal_date: Date """ เนื้อหาของญัตติ """ text: String """ เงื่อนไขของการผ่านญัตติ """ requirement: String } """ กฏหมายหรือร่างกฏหมาย """ type Bill implements Motion @node { """ ID แบบสุ่ม """ id: ID! @id """ องค์กรที่มีส่วนเกี่ยวข้องในการพิจารณา เช่น สส. สว. ชุดใด """ organizations: [Organization!]! @relationship(type: "CREATED_IN", properties: "Relation", direction: OUT) """ ผู้เสนอ """ creators: [MotionCreator!]! @relationship(type: "CREATED_BY", properties: "Relation", direction: OUT) """ ประเภทผู้เสนอ """ creator_type: BillCreatorType! """ เลข ID ของหน้าข้อมูลกฎหมายในเว็บไซต์ lis.parliament """ lis_id: Int! """ จำนวนรายชื่อของประชาชนที่สนับสนุน (ในกรณีที่ประชาชนเป็นคนเสนอ) """ people_signature_count: Int """ ชื่อทางการ """ title: String! """ วันที่รับร่างเข้ากระบวนการ """ proposal_date: Date """ เนื้อหา """ text: String """ เงื่อนไขของการผ่านร่าง """ requirement: String """ ขั้นตอนในประบวนการพิจารณากฏหมาย """ events: [BillEvent!]! @relationship(type: "IN", properties: "Relation", direction: IN) """ ประเภท """ classification: BillType! """ ชื่อเล่นที่เป็นที่รู้จักโดยทั่วไป (ตั้งโดยทีมทำข้อมูล) """ nickname: String """ หมายเลขทะเบียนรับจากระบบ LIS """ acceptance_number: String """ เลขฉบับ (มีเมื่อร่างผ่าน) """ issue_number: String """ เลขปี (มีเมื่อร่างผ่าน) """ issue_year: String """ ติดแท็กเรื่องที่เกี่ยวข้อง """ categories: [String!] """ ผู้ร่วมเสนอ """ co_creators: [Person!]! @relationship(type: "CO_CREATED_BY", properties: "Relation", direction: OUT) """ สถานะของร่างกฎหมาย """ status: BillStatus! """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การเป็นสมาชิก อ้างอิงจาก https://www.popoloproject.com/specs/membership.html """ type Membership @node @authorization( filter: [ { where: {} } { requireAuthentication: false where: { node: { NOT: { members: { all: { Person: { publish_status: { eq: "UNPUBLISHED" } } } } } } } } ] ) { """ ID แบบสุ่ม """ id: ID! @id """ สมาชิก """ members: [Member!]! @relationship(type: "HELD", properties: "Relation", direction: IN) """ ตำแหน่ง """ posts: [Post!]! @relationship(type: "AS", properties: "Relation", direction: OUT) """ ประเภทที่ถูกแบ่ง เช่น วิธีการจัดตั้งหรือกลุ่มอาชีพของ สว. """ label: String """ จังหวัด (ในกรณีของ สส.เขต) """ province: String """ เลขที่เขตเลือกตั้ง (ในกรณีของ สส.เขต) """ district_number: Int """ ลำดับในบัญชีรายชื่อ (ในกรณีของ สส.บัญชีรายชื่อ) """ list_number: Int """ วันที่เริ่ม """ start_date: Date! """ วันที่สิ้นสุด """ end_date: Date """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การประกาศร่างตกไป """ type BillRejectEvent implements Event @node { """ ID แบบสุ่ม """ id: ID! @id """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: IN) """ กฏหมายที่เกี่ยวข้อง """ bills: [Bill!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ คำอธิบาย """ description: String """ วันที่เริ่ม """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ เหตุผลที่ร่างตกไป """ reject_reason: String! """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การลงคะแนนเสียงในมติ อ้างอิงจาก https://www.popoloproject.com/specs/vote.html """ type Vote @node @authorization( filter: [ { where: {} } { requireAuthentication: false where: { node: { vote_events: { some: { publish_status: { eq: "PUBLISHED" } } } } } } ] ) @limit(max: 1000) { """ ID แบบสุ่ม """ id: ID! @id """ มติที่ลงคะแนนเสียง """ vote_events: [VoteEvent!]! @relationship(type: "VOTED_IN", properties: "Relation", direction: OUT) """ บุคคลที๋โหวต """ voters: [Person!]! @relationship(type: "VOTED_BY", properties: "Relation", direction: OUT) """ ลำดับที่ (จากตารางในรายงานการประชุมของ MSBIS) """ vote_order: String """ เลขที่บัตร (จากตารางในรายงานการประชุมของ MSBIS) """ badge_number: String """ ชื่อ-สกุล (จากตารางในรายงานการประชุมของ MSBIS) """ voter_name_raw: String """ ชื่อสังกัด (จากตารางในรายงานการประชุมของ MSBIS) """ voter_party: String """ การออกเสียงลงคะแนน """ option: String! """ การออกเสียงลงคะแนน ภาษาอังกฤษ """ option_en: String @customResolver(requires: "option") """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ รายละเอียดการลงมติที่มาจากเว็บ lis """ type BillVoteEvent implements Event @node { """ ID แบบสุ่ม """ id: ID! @id """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: IN) """ กฏหมายที่เกี่ยวข้อง """ bills: [Bill!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ อีเวนต์การโหวต """ vote_events: [VoteEvent!]! @relationship( type: "HAS_VOTE_EVENT" properties: "Relation" direction: OUT ) """ การลงมติอยู่ในขั้นตอนใดของกระบวนการพิจารณากฏหมายใด """ classification: VoteEventType """ คำอธิบายคร่าวๆ """ description: String """ วันที่เริ่มต้น """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ ชื่อวาระจาก MSBIS """ title: String """ ชื่อเล่นสำหรับคนทั่วไป """ nickname: String """ ผลการลงมติ """ result: String """ เงื่อนไขในการผ่านมติ """ pass_condition: String """ จำนวนผู้ที่เห็นด้วย (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ agree_count: Int """ จำนวนผู้ที่ไม่เห็นด้วย (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ disagree_count: Int """ จำนวนผู้ที่งดออกเสียง (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ abstain_count: Int """ จำนวนผู้ที่ไม่ลงคะแนนเสียง (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ novote_count: Int """ ID ใน URL ของ MSBIS """ msbis_id: Int """ ครั้งที่ประชุม(ปีที่ ... สมัย ... ครั้งที่ ...) """ session_identifier: String """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การประกาศเป็นกฎหมาย """ type BillEnactEvent implements Event @node { """ ID แบบสุ่ม """ id: ID! @id """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: IN) """ กฏหมายที่เกี่ยวข้อง """ bills: [Bill!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ ชื่อร่างหลังจากประกาศเป็นกฎหมาย """ title: String """ คำอธิบาย """ description: String """ วันที่เริ่ม """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ ชื่ออื่นๆของ Person """ type AlternatePersonName @node { """ ID ที่มาจากชื่อองค์กร """ id: ID! @id """ ชื่อจริง """ firstname: String! """ ชื่อกลาง """ middlename: String """ นามสกุล """ lastname: String! """ ชื่อเต็มที่ประกอบด้วยชื่อ ชื่อกลาง และนามสกุล """ name: String! @customResolver(requires: "firstname middlename lastname") """ คำอธิบาย """ description: String """ entity เจ้าของชื่อ """ named_entity: [Person!]! @relationship(type: "KNOWN_AS", properties: "Relation", direction: IN) # TODO change relation type """ วันที่เริ่มต้นใช้ชื่อนี้ """ start_date: Date """ วันที่สิ้นสุดใช้ชื่อนี้ """ end_date: Date """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การลงมติ """ type VoteEvent implements Event @node @authorization( filter: [ { where: {} } { requireAuthentication: false where: { node: { publish_status: { eq: "PUBLISHED" } } } } ] ) { """ ID แบบสุ่ม """ id: ID! @id """ การลงคะแนนเสียงของผู้เข้าร่วมประชุม """ votes: [Vote!]! @relationship(type: "VOTED_IN", properties: "Relation", direction: IN) """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: IN) """ กฏหมายที่เกี่ยวข้อง """ bills: [Bill!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ อีเวนต์การโหวตในร่างกฎหมาย """ bill_vote_events: [BillVoteEvent!]! @relationship(type: "HAS_VOTE_EVENT", properties: "Relation", direction: IN) """ การลงมติอยู่ในขั้นตอนใดของกระบวนการพิจารณากฏหมายใด """ classification: VoteEventType """ คำอธิบายคร่าวๆ """ description: String """ วันที่เริ่มต้น """ start_date: Date! """ วันที่สิ้นสุด """ end_date: Date! """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ ชื่อวาระจาก MSBIS """ title: String! """ ชื่อเล่นสำหรับคนทั่วไป """ nickname: String """ ผลการลงมติ """ result: String """ เงื่อนไขในการผ่านมติ """ pass_condition: String """ จำนวนผู้ที่เห็นด้วย (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ agree_count: Int """ จำนวนผู้ที่ไม่เห็นด้วย (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ disagree_count: Int """ จำนวนผู้ที่งดออกเสียง (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ abstain_count: Int """ จำนวนผู้ที่ไม่ลงคะแนนเสียง (จากหัวเอกสารรายงานการประชุมของ MSBIS) """ novote_count: Int """ ID ใน URL ของ MSBIS """ msbis_id: Int """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การพิจารณาร่างพระราชบัญญัติ เป็นร่างหลัก """ type BillMergeEvent implements Event @node { """ ID แบบสุ่ม """ id: ID! @id """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: IN) """ กฏหมายที่เกี่ยวข้อง """ bills: [Bill!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ คำอธิบาย """ description: String """ วันที่เริ่ม """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ กฏหมายร่างหลัก """ main_bill_id: String """ จำนวนร่างกฎหมายที่ถูกรวม """ total_merged_bills: Int! """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ การนำขึ้นทูลเกล้าทูลกระหม่อมถวาย """ type BillRoyalAssentEvent implements Event @node { """ ID แบบสุ่ม """ id: ID! @id """ องค์กรที่เกี่ยวข้อง """ organizations: [Organization!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: IN) """ กฏหมายที่เกี่ยวข้อง """ bills: [Bill!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ คำอธิบาย """ description: String """ วันที่เริ่ม """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ ผลการนำขึ้นทูลเกล้าทูลกระหม่อมถวาย """ result: String """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ ชื่ออื่นๆของ entity ต่างๆ """ type AlternateName @node { """ ID ที่มาจากชื่อองค์กร """ id: ID! @id """ ชื่อ """ name: String! """ ชื่อ ภาษาอังกฤษ """ name_en: String """ คำอธิบาย """ description: String """ entity เจ้าของชื่อ """ named_entity: [NamedEntity!]! @relationship(type: "KNOWN_AS", properties: "Relation", direction: IN) """ วันที่เริ่มต้นใช้ชื่อนี้ """ start_date: Date """ วันที่สิ้นสุดใช้ชื่อนี้ """ end_date: Date """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ ลิงก์ไปยังเว็บไซต์ภายนอกที่เกี่ยวข้อง """ type Link @node @authorization( filter: [ { where: {} } { requireAuthentication: false where: { node: { NOT: { owners: { all: { Person: { publish_status: { eq: "UNPUBLISHED" } } } } } } } } ] ) { """ ID แบบสุ่ม """ id: ID! @id """ URL """ url: String! """ คำอธิบาย """ note: String """ เว็บไซต์ภายเชื่อมโยงกับอะไรในฐานข้อมูล """ owners: [LinkOwner!]! @relationship(type: "HAVE", properties: "Relation", direction: IN) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ บุคคลที่เกี่ยวข้องทางการเมือง เช่น สมาชิกสภา สมาชิกพรรคการเมือง ฯลฯ อ้างอิงจาก https://www.popoloproject.com/specs/person.html """ type Person @node @authorization( filter: [ { where: {} } { requireAuthentication: false where: { node: { publish_status: { eq: "PUBLISHED" } } } } ] ) @limit(max: 1000) { """ ID ในรูปแบบชื่อเต็มที่เปลี่ยนช่องว่างเป็น "-" """ id: ID! @id """ คำนำหน้า """ prefix: String! """ ชื่อจริง """ firstname: String! """ ชื่อกลาง """ middlename: String """ นามสกุล """ lastname: String! """ ชื่อเต็มที่ประกอบด้วยชื่อ ชื่อกลาง และนามสกุล """ name: String! @customResolver(requires: "firstname middlename lastname") """ ชื่อจริง ภาษาอังกฤษ """ firstname_en: String """ ชื่อกลาง ภาษาอังกฤษ """ middlename_en: String """ นามสกุล ภาษาอังกฤษ """ lastname_en: String """ ชื่อเต็มภาษาอังกฤษที่ประกอบด้วยชื่อ ชื่อกลาง และนามสกุล """ name_en: String @customResolver(requires: "firstname_en middlename_en lastname_en") """ ชื่ออื่นๆ """ other_names: [OtherNames!]! @relationship(type: "KNOWN_AS", properties: "Relation", direction: OUT) # TODO change relation type """ อีเมล """ email: String """ เพศโดยกำเนิด """ gender: Gender """ วันเกิด """ birth_date: Date """ วันเสียชีวิต """ death_date: Date """ ประวัติการศึกษา """ educations: String """ ประวัติการทำงาน """ previous_occupations: String """ รูปภาพ """ image: String """ สัญชาติ """ national_identity: String """ สถานะการเผยแพร่ """ publish_status: PublishStatus! """ การเป็นสมาชิกในองค์กร """ memberships: [Membership!]! @relationship(type: "HELD", properties: "Relation", direction: OUT) """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ การโหวตในมติ """ votes: [Vote!]! @relationship(type: "VOTED_BY", properties: "Relation", direction: IN) """ กฏหมายหรือร่างกฏหมายที่เสนอในนามบุคคล """ created_motions: [Motion!]! @relationship(type: "CREATED_BY", properties: "Relation", direction: IN) """ กฏหมายหรือร่างกฏหมายที่เสนอในนามบุคคล """ co_created_motions: [Motion!]! @relationship(type: "CO_CREATED_BY", properties: "Relation", direction: IN) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ ตำแหน่งในองค์กร เช่น ประธานสภา หัวหน้าพรรค ฯลฯ อ้างอิงจาก https://www.popoloproject.com/specs/post.html """ type Post @node { """ ID แบบสุ่ม """ id: ID! @id """ ชื่อตำแหน่งแบบเต็ม (มีชื่อองกรณ์) """ label: String! @customResolver(requires: "role organizations { name classification }") """ ชื่อตำแหน่งแบบสั้น """ role: String! """ วันที่เริ่ม """ start_date: Date """ วันที่สิ้นสุด """ end_date: Date """ องค์กรที่มีตำแหน่งนี้ """ organizations: [Organization!]! @relationship(type: "IN", properties: "Relation", direction: OUT) """ การเป็นสมาชิกในตำแหน่งนี้ """ memberships: [Membership!]! @relationship(type: "AS", properties: "Relation", direction: IN) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ องค์กรที่เกี่ยวข้องทางการเมือง เช่น สส. สว. ครม. พรรคการเมือง ฯลฯ อ้างอิงจาก https://www.popoloproject.com/specs/organization.html """ type Organization @node { """ ID ที่มาจากชื่อองค์กร """ id: ID! """ ชื่อ """ name: String! """ ชื่อ ภาษาอังกฤษ """ name_en: String """ ชื่ออื่นๆ """ other_names: [AlternateName!]! @relationship(type: "KNOWN_AS", properties: "Relation", direction: OUT) # TODO change relation type """ คำอธิบาย """ description: String """ ประเภท """ classification: OrganizationType! """ ตัวย่อ """ abbreviation: String @customResolver(requires: "classification") """ ชุดที่ / คณะที่ (สำหรับ สส. สว. ครม.) """ term: Int @customResolver(requires: "classification name") """ วันที่ก่อตั้ง """ founding_date: Date """ วันที่ปิดตัวหรือหมดวาระ """ dissolution_date: Date """ โลโก้ """ image: String """ สีในการแสดงผล """ color: String """ องค์กรที่อยู่เหนือกว่า """ parents: [Organization!]! @relationship(type: "UNDER", properties: "Relation", direction: OUT) """ องค์กรย่อยที่อยู่ภายใต้ """ children: [Organization!]! @relationship(type: "UNDER", properties: "Relation", direction: IN) """ ตำแหน่งที่มีในองค์กร """ posts: [Post!]! @relationship(type: "IN", properties: "Relation", direction: IN) """ การเป็นสมาชิกในองค์กรอื่น เช่น การเป็นพรรคฝ่ายรัฐบาล/ค้านในครม. """ memberships: [Membership!]! @relationship(type: "HELD", properties: "Relation", direction: OUT) """ กฏหมายหรือร่างกฏหมายที่เสนอในนามองค์กร """ motions: [Motion!]! @relationship(type: "CREATED_IN", properties: "Relation", direction: IN) """ กิจกรรมที่องค์กรนี้เกี่ยวข้อง """ events: [Event!]! @relationship(type: "HELD_EVENT", properties: "Relation", direction: OUT) """ เว็บไซต์ภายนอกที่เกี่ยวข้อง """ links: [Link!]! @relationship(type: "HAVE", properties: "Relation", direction: OUT) """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ ความสัมพันธ์ทั่วไป """ type Relation @relationshipProperties { """ ID แบบสุ่ม """ id: ID! @id """ วันที่เพิ่มลงในฐานข้อมูล """ created_at: DateTime! @timestamp(operations: [CREATE]) """ วันที่แก้ไขข้อมูลล่าสุด """ updated_at: DateTime @timestamp(operations: [UPDATE]) } """ ผู้เสนอร่างกฏหมาย เป็นบุคคลหรือองค์กร """ union MotionCreator = Person | Organization """ เจ้าของลิงก์ไปยังเว็บไซต์ภายนอกที่เกี่ยวข้อง สามารถเป็นบุคคล องค์กร หรือกฏหมาย """ union LinkOwner = | Person | Organization | Membership | Bill | VoteEvent | BillVoteEvent | BillMergeEvent | BillEnactEvent | BillRejectEvent | BillRoyalAssentEvent """ entity ที่มีชื่อ """ union NamedEntity = Person | Organization """ เหตุการที่เกี่ยวข้องกับกฏหมายหรือร่างกฏหมาย """ union BillEvent = | BillEnactEvent | BillMergeEvent | BillRejectEvent | BillRoyalAssentEvent | BillVoteEvent """ สมาชิกขององค์กร อาจจะเป็น บุคคล หรือ องค์กร (เช่นพรรคร่วมรัฐบาล พรรคฝ่ายค้าย) """ union Member = Person | Organization """ ชื่ออื่นๆ """ union OtherNames = AlternateName | AlternatePersonName ```