✨ Challenges
This commit is contained in:
parent
caff256949
commit
3f5654efb4
5
.idea/.gitignore
vendored
Normal file
5
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
12
.idea/Fuxi.iml
Normal file
12
.idea/Fuxi.iml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
57
.idea/codeStyles/Project.xml
Normal file
57
.idea/codeStyles/Project.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<HTMLCodeStyleSettings>
|
||||||
|
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||||
|
</HTMLCodeStyleSettings>
|
||||||
|
<JSCodeStyleSettings version="0">
|
||||||
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||||
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
|
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||||
|
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||||
|
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||||
|
</JSCodeStyleSettings>
|
||||||
|
<TypeScriptCodeStyleSettings version="0">
|
||||||
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||||
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
|
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||||
|
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||||
|
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||||
|
</TypeScriptCodeStyleSettings>
|
||||||
|
<VueCodeStyleSettings>
|
||||||
|
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
||||||
|
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
||||||
|
</VueCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="HTML">
|
||||||
|
<option name="SOFT_MARGINS" value="120" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JavaScript">
|
||||||
|
<option name="SOFT_MARGINS" value="120" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="TypeScript">
|
||||||
|
<option name="SOFT_MARGINS" value="120" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="Vue">
|
||||||
|
<option name="SOFT_MARGINS" value="120" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Fuxi.iml" filepath="$PROJECT_DIR$/.idea/Fuxi.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.idea/sqldialects.xml
Normal file
7
.idea/sqldialects.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="SqlDialectMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$/supabase/migrations/20231210135930_challenges.sql" dialect="GenericSQL" />
|
||||||
|
<file url="PROJECT" dialect="PostgreSQL" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -1,13 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-message-provider>
|
<n-message-provider>
|
||||||
|
<n-dialog-provider>
|
||||||
<nuxt-layout>
|
<nuxt-layout>
|
||||||
<nuxt-loading-indicator />
|
<nuxt-loading-indicator />
|
||||||
<nuxt-page />
|
<nuxt-page />
|
||||||
</nuxt-layout>
|
</nuxt-layout>
|
||||||
|
</n-dialog-provider>
|
||||||
</n-message-provider>
|
</n-message-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NMessageProvider } from "naive-ui";
|
import { NMessageProvider, NDialogProvider } from "naive-ui";
|
||||||
import "@/assets/css/index.css";
|
import "@/assets/css/index.css";
|
||||||
</script>
|
</script>
|
||||||
|
Binary file not shown.
11
application/components/problem/solution/program.vue
Normal file
11
application/components/problem/solution/program.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -22,6 +22,7 @@
|
|||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@guolao/vue-monaco-editor": "^1.4.1",
|
||||||
"@ibm/plex": "^6.3.0",
|
"@ibm/plex": "^6.3.0",
|
||||||
"@nuxtjs/mdc": "^0.2.8",
|
"@nuxtjs/mdc": "^0.2.8",
|
||||||
"@supabase/supabase-js": "^2.39.0",
|
"@supabase/supabase-js": "^2.39.0",
|
||||||
|
30
application/pages/about.vue
Normal file
30
application/pages/about.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="max-w-[720px] mx-auto">
|
||||||
|
<n-card>
|
||||||
|
<brand-header />
|
||||||
|
|
||||||
|
<div>Get everyone interested in programming.</div>
|
||||||
|
|
||||||
|
<n-divider class="mx-[-24px] w-[calc(100%+48px)]" />
|
||||||
|
|
||||||
|
<div class="text-gray text-xs">
|
||||||
|
<div>
|
||||||
|
<nuxt-link class="link" target="_blank" to="https://smartsheep.studio">Made by SmartSheep Studio.</nuxt-link>
|
||||||
|
Proprietary software.
|
||||||
|
</div>
|
||||||
|
<div>Fuxi Development Team © {{ new Date().getFullYear() }}</div>
|
||||||
|
</div>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { NCard, NDivider } from "naive-ui";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.link {
|
||||||
|
all: unset;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
116
application/pages/challenges/[id].vue
Normal file
116
application/pages/challenges/[id].vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<div class="md:max-w-[720px] mx-auto">
|
||||||
|
<n-card segmented>
|
||||||
|
<template #header>
|
||||||
|
<n-page-header @back="navigateTo('/')">
|
||||||
|
<template #title>Challenge #{{ challenge?.id }}</template>
|
||||||
|
<template #subtitle>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<n-tag size="small" class="case-capital">{{ challenge?.status?.replaceAll("-", " ") }}</n-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</n-page-header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<client-only>
|
||||||
|
<vue-monaco-editor
|
||||||
|
:options="options"
|
||||||
|
v-model:value="answer.code"
|
||||||
|
class="min-h-[360px] code-editor"
|
||||||
|
/>
|
||||||
|
</client-only>
|
||||||
|
|
||||||
|
<n-divider class="mx-[-24px] w-[calc(100%+48px)] divider-below-code" />
|
||||||
|
|
||||||
|
<template #action>
|
||||||
|
<div class="w-full flex justify-between">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<n-button secondary circle class="rounded-[4px]" type="warning" :disabled="submitting" @click="save">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon :component="Save" />
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<n-button secondary type="error" :disabled="submitting" @click="abandon">放弃</n-button>
|
||||||
|
<n-button type="primary" :disabled="submitting" @click="submit">提交</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { NButton, NCard, NDivider, NPageHeader, NTag, NIcon, useDialog, useMessage } from "naive-ui";
|
||||||
|
import { VueMonacoEditor } from "@guolao/vue-monaco-editor";
|
||||||
|
import { Save } from "@vicons/carbon";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const client = useSupabaseClient();
|
||||||
|
const message = useMessage();
|
||||||
|
const dialog = useDialog();
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
minimap: { enabled: false }
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitting = ref(false);
|
||||||
|
|
||||||
|
const { data: challenge } = await client
|
||||||
|
.from("challenges")
|
||||||
|
.select<any, any>("*")
|
||||||
|
.eq("id", route.params.id)
|
||||||
|
.single();
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: challenge ? `挑战 #${challenge.id}` : "挑战 #404"
|
||||||
|
});
|
||||||
|
|
||||||
|
const answer = ref(challenge?.answer ?? {});
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function abandon() {
|
||||||
|
const instance = dialog.warning({
|
||||||
|
title: "警告",
|
||||||
|
content: "你确定要放弃该次挑战?这会让该挑战立刻转化为放弃状态,并且扣除 5 点社会信用点,三思而后行!",
|
||||||
|
positiveText: "确定",
|
||||||
|
negativeText: "再试试",
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
await client
|
||||||
|
.from("challenges")
|
||||||
|
// @ts-ignore
|
||||||
|
.update<any>({ status: "abandoned" })
|
||||||
|
.eq("id", challenge.id);
|
||||||
|
|
||||||
|
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
|
||||||
|
|
||||||
|
instance.loading = true
|
||||||
|
message.info("已放弃挑战该题");
|
||||||
|
|
||||||
|
await delay(1850);
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.code-editor {
|
||||||
|
min-width: calc(100% + 48px);
|
||||||
|
margin-top: -20px;
|
||||||
|
margin-left: -24px;
|
||||||
|
margin-right: -24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider-below-code {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="md:max-w-[720px] mx-auto">
|
<div class="md:max-w-[720px] mx-auto">
|
||||||
<problems-list />
|
<problem-list />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -31,22 +31,90 @@
|
|||||||
</div>
|
</div>
|
||||||
<n-empty v-else description="本题无公开样例" />
|
<n-empty v-else description="本题无公开样例" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<template #action>
|
||||||
|
<div class="w-full flex justify-end">
|
||||||
|
<n-button v-if="!answering" type="primary" :loading="submitting" @click="doChallenge">试答该题</n-button>
|
||||||
|
<div v-else>
|
||||||
|
<n-button type="primary" disabled>
|
||||||
|
<template #icon>
|
||||||
|
<n-icon :component="Checkmark" />
|
||||||
|
</template>
|
||||||
|
正在作答
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NCard, NTag, NPageHeader, NDivider, NEmpty } from "naive-ui";
|
import { NCard, NTag, NPageHeader, NDivider, NEmpty, NButton, NIcon, useMessage } from "naive-ui";
|
||||||
|
import { Checkmark } from "@vicons/carbon";
|
||||||
import "prismjs/themes/prism.css";
|
import "prismjs/themes/prism.css";
|
||||||
import "prismjs/prism";
|
import "prismjs/prism";
|
||||||
|
|
||||||
|
const user = useSupabaseUser();
|
||||||
const client = useSupabaseClient();
|
const client = useSupabaseClient();
|
||||||
|
const message = useMessage();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const { data: problem } = await client.from("problems").select<any, any>("*").eq("id", route.params.id).single();
|
const submitting = ref(false);
|
||||||
|
const answering = ref(false);
|
||||||
|
|
||||||
|
const { data: problem } = await client
|
||||||
|
.from("problems")
|
||||||
|
.select<any, any>("*")
|
||||||
|
.eq("id", route.params.id)
|
||||||
|
.single();
|
||||||
const { data: example } = await client
|
const { data: example } = await client
|
||||||
.from("problem_cases")
|
.from("problem_cases")
|
||||||
.select<any, any>("*")
|
.select<any, any>("*")
|
||||||
.eq("problem", route.params.id)
|
.eq("problem", route.params.id)
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: problem?.title ?? "未知题目"
|
||||||
|
});
|
||||||
|
|
||||||
|
async function doChallenge() {
|
||||||
|
if (problem == null) return;
|
||||||
|
|
||||||
|
submitting.value = true;
|
||||||
|
|
||||||
|
let { data } = await client
|
||||||
|
.from("challenges")
|
||||||
|
.select<any, any>("id")
|
||||||
|
.eq("problem", problem?.id)
|
||||||
|
.eq("status", "in-progress")
|
||||||
|
.single();
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
const res = await client
|
||||||
|
.from("challenges")
|
||||||
|
// @ts-ignore
|
||||||
|
.insert<any>({
|
||||||
|
answers: {},
|
||||||
|
details: {},
|
||||||
|
status: "in-progress",
|
||||||
|
problem: problem.id,
|
||||||
|
author: user.value?.id
|
||||||
|
})
|
||||||
|
.select<any, any>()
|
||||||
|
.single();
|
||||||
|
|
||||||
|
if (res.error != null) {
|
||||||
|
message.error(`Something went wrong... ${res.error.message}`);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
data = res.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting.value = false;
|
||||||
|
answering.value = true;
|
||||||
|
navigateTo(`/challenges/${data.id}`, { open: { target: "_blank" } });
|
||||||
|
setTimeout(() => answering.value = false, 3000);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
create table public.profiles (
|
create table public.profiles
|
||||||
|
(
|
||||||
id uuid not null references auth.users on delete cascade,
|
id uuid not null references auth.users on delete cascade,
|
||||||
username varchar(64),
|
username varchar(64),
|
||||||
nickname varchar(256),
|
nickname varchar(256),
|
||||||
school int8,
|
school int8,
|
||||||
primary key (id)
|
primary key (id)
|
||||||
);
|
);
|
||||||
alter table public.profiles enable row level security;
|
|
||||||
|
alter table public.profiles
|
||||||
|
enable row level security;
|
||||||
|
|
||||||
create policy "Public profiles are viewable by everyone." on profiles for
|
create policy "Public profiles are viewable by everyone." on profiles for
|
||||||
select using (true);
|
select using (true);
|
||||||
|
|
||||||
create policy "Users can insert their own profile." on profiles for
|
create policy "Users can insert their own profile." on profiles for
|
||||||
insert with check (auth.uid() = id);
|
insert with check (auth.uid() = id);
|
||||||
|
|
||||||
create policy "Users can update own profile." on profiles for
|
create policy "Users can update own profile." on profiles for
|
||||||
update using (auth.uid() = id);
|
update using (auth.uid() = id);
|
@ -1,4 +1,5 @@
|
|||||||
create table public.problems (
|
create table public.problems
|
||||||
|
(
|
||||||
id bigint generated by default as identity,
|
id bigint generated by default as identity,
|
||||||
title text not null,
|
title text not null,
|
||||||
description text not null,
|
description text not null,
|
||||||
@ -12,10 +13,15 @@ create table public.problems (
|
|||||||
constraint problems_pkey primary key (id),
|
constraint problems_pkey primary key (id),
|
||||||
constraint problems_author_fkey foreign key (author) references auth.users (id)
|
constraint problems_author_fkey foreign key (author) references auth.users (id)
|
||||||
) tablespace pg_default;
|
) tablespace pg_default;
|
||||||
alter table public.problems enable row level security;
|
|
||||||
|
alter table public.problems
|
||||||
|
enable row level security;
|
||||||
|
|
||||||
create policy "Public problems are viewable by everyone." on problems for
|
create policy "Public problems are viewable by everyone." on problems for
|
||||||
select using (true);
|
select using (true);
|
||||||
create table public.problem_cases (
|
|
||||||
|
create table public.problem_cases
|
||||||
|
(
|
||||||
id bigint generated by default as identity,
|
id bigint generated by default as identity,
|
||||||
spec jsonb not null,
|
spec jsonb not null,
|
||||||
limitations jsonb not null,
|
limitations jsonb not null,
|
||||||
@ -25,6 +31,9 @@ create table public.problem_cases (
|
|||||||
constraint problem_cases_pkey primary key (id),
|
constraint problem_cases_pkey primary key (id),
|
||||||
constraint problem_cases_author_fkey foreign key (problem) references public.problems (id)
|
constraint problem_cases_author_fkey foreign key (problem) references public.problems (id)
|
||||||
) tablespace pg_default;
|
) tablespace pg_default;
|
||||||
alter table public.problem_cases enable row level security;
|
|
||||||
|
alter table public.problem_cases
|
||||||
|
enable row level security;
|
||||||
|
|
||||||
create policy "Public problem cases are viewable by everyone." on problem_cases for
|
create policy "Public problem cases are viewable by everyone." on problem_cases for
|
||||||
select using (is_hidden = false);
|
select using (is_hidden = false);
|
@ -1,4 +1,5 @@
|
|||||||
create table public.challenges (
|
create table public.challenges
|
||||||
|
(
|
||||||
id bigint generated by default as identity,
|
id bigint generated by default as identity,
|
||||||
answers jsonb not null,
|
answers jsonb not null,
|
||||||
details jsonb not null,
|
details jsonb not null,
|
||||||
@ -10,5 +11,26 @@ create table public.challenges (
|
|||||||
constraint challenges_author_fkey foreign key (author) references auth.users (id),
|
constraint challenges_author_fkey foreign key (author) references auth.users (id),
|
||||||
constraint challenges_problem_fkey foreign key (problem) references public.problems (id)
|
constraint challenges_problem_fkey foreign key (problem) references public.problems (id)
|
||||||
) tablespace pg_default;
|
) tablespace pg_default;
|
||||||
|
|
||||||
alter table public.challenges enable row level security;
|
alter table public.challenges enable row level security;
|
||||||
create policy "The challagers can see their challenges" on "public"."challenges" for select to public using (auth.uid() = author) with check (true)
|
|
||||||
|
create
|
||||||
|
policy "Enable insert for everyone" on "public"."challenges"
|
||||||
|
as permissive for insert
|
||||||
|
to public
|
||||||
|
with check (true);
|
||||||
|
|
||||||
|
create
|
||||||
|
policy "Enable read access for users' own items" on "public"."challenges"
|
||||||
|
as permissive for
|
||||||
|
select
|
||||||
|
to public
|
||||||
|
using (author = auth.uid());
|
||||||
|
|
||||||
|
create
|
||||||
|
policy "Enable update access for users' own items" on "public"."challenges"
|
||||||
|
as permissive for
|
||||||
|
update
|
||||||
|
to public
|
||||||
|
using (author = auth.uid())
|
||||||
|
with check (author = auth.uid())
|
Loading…
Reference in New Issue
Block a user