Implement Automated Status Management

One of the key functions of a project management app is tracking project status.

Let's implement this by creating a trigger that monitors the task updates and automatically calls the pipeline resolver to update the status of a Project.

Tutorial steps

  1. Activate the Executor service
  2. Create updateProjectStatus pipeline resolver
  3. Add the trigger in executor.cue manifest file
  4. Enable PublishRecordEvents settings
  5. Apply the change using tailorctl
  6. Verify the trigger

1. Activate the Executor service

To activate the Executor service, add executor service to the list of services in the workspace.cue file as the following.

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> v2</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)">	...</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/template/services/executor</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">)</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">v2.#Workspace </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">	Apps: [</span></span>
<span><span style="color: var(--shiki-color-text)">		application</span></span>
<span><span style="color: var(--shiki-color-text)">	]</span></span>
<span><span style="color: var(--shiki-color-text)">	Services: [tailordb</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> pipeline</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> auth</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> executor]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

2. Create updateProjectStatus pipeline resolver

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> resolvers</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">github.com/tailor-platform/tailorctl/schema/v2/pipeline</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/template/services/pipeline</span><span style="color: var(--shiki-color-text)">:settings</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">github.com/tailor-platform/tailorctl/schema/v2/common</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">)</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">projectResult: {</span></span>
<span><span style="color: var(--shiki-color-text)">	Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">projectResult</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Fields: [</span></span>
<span><span style="color: var(--shiki-color-text)">		{Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">projectId</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Type: pipeline.ID</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required: </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">		{Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">status</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Type: pipeline.String }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">	]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">updateProjectStatus: pipeline.#Resolver </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">	Authorization: pipeline.#AuthInsecure</span></span>
<span><span style="color: var(--shiki-color-text)">	Name:        </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">updateProjectStatus</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Update the project status to completed when all tasks are completed</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Response: {Type: projectResult}</span></span>
<span><span style="color: var(--shiki-color-text)">	Inputs: [</span></span>
<span><span style="color: var(--shiki-color-text)">		{</span></span>
<span><span style="color: var(--shiki-color-text)">			Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">input</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">			Required: </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">			Type: {</span></span>
<span><span style="color: var(--shiki-color-text)">				Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">updateProjectStatusInput</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">				Fields: [</span></span>
<span><span style="color: var(--shiki-color-text)">					{Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">projectId</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Type: pipeline.ID</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required: </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">				]</span></span>
<span><span style="color: var(--shiki-color-text)">			}</span></span>
<span><span style="color: var(--shiki-color-text)">		}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">	]</span></span>
<span><span style="color: var(--shiki-color-text)">	Pipelines: [</span></span>
<span><span style="color: var(--shiki-color-text)">		{</span></span>
<span><span style="color: var(--shiki-color-text)">			Name:        </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">getTaskInfo</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">			Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Get all task for the project</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">			Invoker:     settings.adminInvoker</span></span>
<span><span style="color: var(--shiki-color-text)">			PreScript:   </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">			{</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				&#39;projectId&#39;: context.args.input.projectId,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">			}</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">			Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">                Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                   query fetchAllTasksForProject($projectId: ID!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">						tasks(query: {projectId: {eq: $projectId}}) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            collection {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                                id</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                                name</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                                projectId</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                                dueDate</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                                status</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                    }</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">            }</span></span>
<span><span style="color: var(--shiki-color-text)">			PostScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				{</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				&quot;projectId&quot;:context.args.input.projectId,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				&quot;tasks&quot;: args.tasks.collection,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">			}</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">		}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        {</span></span>
<span><span style="color: var(--shiki-color-text)">            Name:        </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">checkTaskStatusAndUpdateProject</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">            Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Update project status</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">            Invoker:     settings.adminInvoker</span></span>
<span><span style="color: var(--shiki-color-text)">            PreHook: common.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">				Expr: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                    (() =&gt; {</span></span>
<span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        // Check if all tasks are completed</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        const allTasksCompleted = context.pipeline.getTaskInfo.tasks.every(task =&gt; </span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            task.status === &#39;Completed&#39;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        );</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        </span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        // Count of completed tasks</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        const completedTasksCount = context.pipeline.getTaskInfo.tasks.filter(task =&gt; </span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            task.status === &#39;Completed&#39;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        ).length;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        </span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        // Return task status information</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        return {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            &#39;projectId&#39;: context.args.input.projectId,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            &#39;status&#39;: allTasksCompleted ? &#39;Completed&#39; : &#39;In Progress&#39;,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            &#39;totalTasksCount&#39;: completedTasksCount.length,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        };</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                    })()</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                    </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">            }</span></span>
<span><span style="color: var(--shiki-color-text)">            Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">                Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                   mutation updateProject($projectId: ID!, $status: String!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        updateProject(id: $projectId, input :{status: $status}) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                            status</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                        }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                    }</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">            }</span></span>
<span><span style="color: var(--shiki-color-text)">            PostScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                &quot;projectId&quot;:context.args.input.projectId,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">                &quot;status&quot;: args.updateProject.status,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">            }</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">        }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">	]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Include the Resolver in the pipeline.cue File

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> pipeline</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">github.com/tailor-platform/tailorctl/schema/v2/pipeline</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/template/services/pipeline/resolvers</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/template/environment</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">)</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">pipeline.#Spec </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">	Namespace: environment.#app.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">	Resolvers: [</span></span>
<span><span style="color: var(--shiki-color-text)">		resolvers.deleteAllTailorDBRecords</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">		resolvers.getProjectStatus</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        resolvers.updateProjectStatus</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">	]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

3. Add the trigger in executor.cue manifest file

To add the triggerUpdateProjectStatus trigger, define the trigger in the executor.cue manifest file.

<span><span style="color: var(--shiki-color-text)">executor.#Spec </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">	Executors: [</span></span>
<span><span style="color: var(--shiki-color-text)">		#triggerUpdateProjectStatus</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">	]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">#triggerUpdateProjectStatus: executor.#Executor </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">	Name:        </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">update-project-status</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Update project status to completed when all tasks are completed</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Trigger: executor.#TriggerEvent </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">		EventType: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailordb.type_record.updated</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">		Condition: common.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">			Expr: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				args.namespaceName == &quot;\(environment.#app.namespace)&quot; &amp;&amp; args.typeName == &quot;Task&quot; &amp;&amp; args.newRecord.status == &quot;Confirmed&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">		}</span></span>
<span><span style="color: var(--shiki-color-text)">	}</span></span>
<span><span style="color: var(--shiki-color-text)">	Target: executor.#TargetTailorGraphql </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">		AppName: environment.#app.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">		Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">			mutation ($input: updateProjectStatusInput!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				updateProjectStatus(</span></span>
<span><span style="color: var(--shiki-token-string-expression)">					input: $input</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">					status</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				}</span></span>
<span><span style="color: var(--shiki-token-string-expression)">			}</span></span>
<span><span style="color: var(--shiki-token-string-expression)">			</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">		Variables: common.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">			Expr: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				({</span></span>
<span><span style="color: var(--shiki-token-string-expression)">					&quot;input&quot;: {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">						&quot;projectId&quot;: args.newRecord.projectId,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">					},</span></span>
<span><span style="color: var(--shiki-token-string-expression)">					&quot;arguments&quot;:args,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				})</span></span>
<span><span style="color: var(--shiki-token-string-expression)">				</span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">		}</span></span>
<span><span style="color: var(--shiki-color-text)">	}</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

4. Enable PublishRecordEvents settings

To ensure that a Project record is updated through the trigger when Task type record status is updated, you'll need to enable PublishRecordEvents in the settings.

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> master</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">github.com/tailor-platform/tailorctl/schema/v2/tailordb</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/template/services/tailordb</span><span style="color: var(--shiki-color-text)">:permissions</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">)</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">Task: tailordb.#Type </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">	Name:        </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Task</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Task Description</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">	Settings: {</span></span>
<span><span style="color: var(--shiki-color-text)">		Aggregation: </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">		PublishRecordEvents: </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">	}</span></span>
<span><span style="color: var(--shiki-color-text)">	Fields: {</span></span>
<span><span style="color: var(--shiki-color-text)">		...</span></span>
<span><span style="color: var(--shiki-color-text)">	}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">	TypePermission: permissions.editorAccess</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

5. Apply the change using tailorctl

Run the following command to apply the changes.

<span><span style="color: var(--shiki-token-comment)"># Apply Executor</span></span>
<span><span style="color: var(--shiki-token-function)">tailorctl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workspace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">apply</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">-m</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">./workspace.cue</span></span>
<span></span>

6. Verify the trigger

Click on the application and select Executors from the navigation to view the created executor in the Console.

Update Project Status Executor

In the console, select GraphQL Playground to update the status of a task with the following script:

<span><span style="color: var(--shiki-token-keyword)">mutation</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  updateTask (id: </span><span style="color: var(--shiki-token-string-expression)">&quot;&lt;TASK-ID&gt;&quot;</span><span style="color: var(--shiki-color-text)">, input: { </span><span style="color: var(--shiki-token-string)">status</span><span style="color: var(--shiki-color-text)"> : </span><span style="color: var(--shiki-token-string-expression)">&quot;Completed&quot;</span><span style="color: var(--shiki-color-text)">}) {</span></span>
<span><span style="color: var(--shiki-color-text)">    status</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

When the script runs, the triggerUpdateProjectStatus trigger monitors task update events and automatically invokes the updateProjectStatus pipeline resolver. This resolver then updates the Project's status by evaluating the status of its associated tasks.